diff --git a/.eslintrc.json b/.eslintrc.json index 87466287..aa47d6b8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,8 +1,10 @@ { "env": { - "node": true + "node": true, + "mocha": true, + "commonjs": true }, - "plugins": ["prettier"], + "plugins": ["prettier", "simple-import-sort", "eslint-plugin-import"], "extends": [ "airbnb-base", "prettier" @@ -11,5 +13,26 @@ "ecmaVersion": 12 }, "rules": { - } + "simple-import-sort/imports": "error", + "no-underscore-dangle": "off", + "camelcase":"off", + "no-unused-vars":"warn", + "func-names": "off", + "no-param-reassign": "warn", + "consistent-return":"warn", + "no-restricted-syntax":"warn", + "global-require":"off", + "radix":"off", + "no-await-in-loop":"off", + "class-methods-use-this":"warn", + "no-return-await":"warn", + "no-new-wrappers": "warn", + "prefer-destructuring": "warn", + "no-shadow":"warn", + "import/order": "warn", + "no-unused-expressions": "warn", + "import/no-extraneous-dependencies": "warn" , + "import/no-unresolved": "warn", + "no-plusplus":"warn", + "no-continue":"off" } } diff --git a/.github/workflows/treetracker-wallet-api-pull-request-ci.yml b/.github/workflows/treetracker-wallet-api-pull-request-ci.yml index ee5f39e3..f1368891 100644 --- a/.github/workflows/treetracker-wallet-api-pull-request-ci.yml +++ b/.github/workflows/treetracker-wallet-api-pull-request-ci.yml @@ -8,7 +8,7 @@ on: branches: - master -env: +env: project-directory: ./ jobs: @@ -34,41 +34,42 @@ jobs: --health-retries 5 steps: - - uses: actions/checkout@v2 - - name: Use Node.js 12.x - uses: actions/setup-node@v1 - with: - node-version: '12.x' - - name: npm clean install - run: npm ci - working-directory: ${{ env.project-directory }} - #- name: run ESLint - # run: npm run lint - #working-directory: ${{ env.project-directory }} + - uses: actions/checkout@v2 + - name: Use Node.js 12.x + uses: actions/setup-node@v1 + with: + node-version: '12.x' + - name: npm clean install + run: npm ci + working-directory: ${{ env.project-directory }} - - name: run db-migrate - run: npm run db-migrate-ci - working-directory: ${{ env.project-directory }} - env: - DATABASE_URL: postgresql://postgres:postgres@postgres/postgres + - name: run ESLint + run: npm run lint + working-directory: ${{ env.project-directory }} - - name: run unit tests - run: npm run test-unit-ci - working-directory: ${{ env.project-directory }} - env: - DATABASE_URL: postgresql://postgres:postgres@postgres/postgres - CI: true - - - name: run integration tests - run: npm run test-integration-ci - working-directory: ${{ env.project-directory }} - env: - DATABASE_URL: postgresql://postgres:postgres@postgres/postgres - CI: true + - name: run db-migrate + run: npm run db-migrate-ci + working-directory: ${{ env.project-directory }} + env: + DATABASE_URL: postgresql://postgres:postgres@postgres/postgres + + - name: run unit tests + run: npm run test-unit-ci + working-directory: ${{ env.project-directory }} + env: + DATABASE_URL: postgresql://postgres:postgres@postgres/postgres + CI: true - - name: run repository tests - run: npm run test-repository - working-directory: ${{ env.project-directory }} - env: - DATABASE_URL: postgresql://postgres:postgres@postgres/postgres - CI: true + - name: run integration tests + run: npm run test-integration-ci + working-directory: ${{ env.project-directory }} + env: + DATABASE_URL: postgresql://postgres:postgres@postgres/postgres + CI: true + + - name: run repository tests + run: npm run test-repository + working-directory: ${{ env.project-directory }} + env: + DATABASE_URL: postgresql://postgres:postgres@postgres/postgres + CI: true diff --git a/.gitignore b/.gitignore index 31bcff5b..ab61c36e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ jwtRS256.key.pub keygen.sh database.json .env -.env.test \ No newline at end of file +.env.test +.vscode \ No newline at end of file diff --git a/.huskyrc b/.huskyrc index 80a43e4d..6ac0557e 100644 --- a/.huskyrc +++ b/.huskyrc @@ -1 +1 @@ -{"hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}} +{"hooks":{"pre-commit": "npm run lint", "commit-msg":"commitlint -E HUSKY_GIT_PARAMS" }} diff --git a/CHANGELOG.md b/CHANGELOG.md index ae7476aa..c74a6e38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,38 @@ +## [1.12.5](https://github.com/Greenstand/treetracker-wallet-api/compare/v1.12.4...v1.12.5) (2021-04-16) + + +### Bug Fixes + +* downgraded husky version to support node-run env required by IDEs ([e3656f5](https://github.com/Greenstand/treetracker-wallet-api/commit/e3656f55f3bbc2b9f98d44af29e8ac258cffda2f)) + +## [1.12.4](https://github.com/Greenstand/treetracker-wallet-api/compare/v1.12.3...v1.12.4) (2021-04-03) + + +### Bug Fixes + +* remove unnecessary CORS ([1b711a2](https://github.com/Greenstand/treetracker-wallet-api/commit/1b711a250d440a2b6bb0c709512e93ba4dd8ea57)) + +## [1.12.3](https://github.com/Greenstand/treetracker-wallet-api/compare/v1.12.2...v1.12.3) (2021-04-02) + + +### Bug Fixes + +* syntax error ([5036b1e](https://github.com/Greenstand/treetracker-wallet-api/commit/5036b1e20b08b6c1221a4026a63ae4bdf0070b0d)) + +## [1.12.2](https://github.com/Greenstand/treetracker-wallet-api/compare/v1.12.1...v1.12.2) (2021-04-02) + + +### Bug Fixes + +* update CORS ([8793c73](https://github.com/Greenstand/treetracker-wallet-api/commit/8793c732eabca832ced6af7d98a6b0ef884295dc)) + +## [1.12.1](https://github.com/Greenstand/treetracker-wallet-api/compare/v1.12.0...v1.12.1) (2021-03-28) + + +### Bug Fixes + +* broken test ([3399cc9](https://github.com/Greenstand/treetracker-wallet-api/commit/3399cc9a5573a3a80c34aed73cfee1592062b4a6)) + # [1.12.0](https://github.com/Greenstand/treetracker-wallet-api/compare/v1.11.2...v1.12.0) (2021-03-26) diff --git a/README.md b/README.md index 912572ef..0a55f219 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ - -#API Documentation +as +#API Documentation To view the specs for the new API visit https://editor.swagger.io and load the YAML file from /docs/api/spec/treetracker-token-api.yaml - # Getting Started - + ## Project Setup Fork this repository to your account and clone from this forked copy. @@ -16,7 +15,8 @@ Open terminal, navigate to a folder to install this project, and run the below c git clone https://github.com/[YOUR GITHUB USERNAME]/treetracker-wallet-api.git ``` -Install all necessary dependencies: + +Install all necessary dependencies: ``` npm install @@ -36,8 +36,10 @@ cat jwtRS256.key.pub ### Database Setup You can use docker-compose, to start a database. To do that: + 1. download and install docker -2. set your /database/database.json file to be: +2. set your /database/database.json file to be: + ``` { "dev": { @@ -51,16 +53,20 @@ You can use docker-compose, to start a database. To do that: } } ``` + your .env file to have a line ``` DATABASE_URL=postgresql://wallet_user:secret@localhost:5432/wallet_user ``` -3. run ```docker-compose up ``` to run the database (or ```docker-compose up -d``` to run detached) -4. then run migrations + +3. run `docker-compose up ` to run the database (or `docker-compose up -d` to run detached) +4. then run migrations + ``` ./node_modules/db-migrate/bin/db-migrate --env dev up -``` +``` + 5. that's it, your db should be running Don't forget to set PUBLIC_KEY and PRIVATE_KEY as described below. @@ -71,31 +77,15 @@ To connect to the database, we need a user and a database. We can either use the To create a new user (role): -` -CREATE ROLE "username" WITH - LOGIN - SUPERUSER - CREATEDB - CREATEROLE - INHERIT - NOREPLICATION - CONNECTION LIMIT -1; -` +`CREATE ROLE "username" WITH LOGIN SUPERUSER CREATEDB CREATEROLE INHERIT NOREPLICATION CONNECTION LIMIT -1;` To set the password: -` -ALTER USER username WITH PASSWORD 'password'; -` +`ALTER USER username WITH PASSWORD 'password';` To create a new database: -` -CREATE DATABASE dbname - WITH - OWNER = username - ENCODING = 'UTF8'; -` +`CREATE DATABASE dbname WITH OWNER = username ENCODING = 'UTF8';` We recommend setting up your Postgres server/database locally and assigning setting up your environment variables in an .env file in your root repository: @@ -115,12 +105,13 @@ If you are using the postgres user: DATABASE_URL="postgresql://postgres@localhost:5432/[database_name]"; ``` -See the .env.example file for the format and structure. +See the .env.example file for the format and structure. Here are some resources to get started on local database set up and migration: -* https://postgresapp.com -* pgAdmin and DBeaver are great GUI options to use for navigating your local db -* https://www.postgresql.org/docs/9.1/app-pgdump.html + +- https://postgresapp.com +- pgAdmin and DBeaver are great GUI options to use for navigating your local db +- https://www.postgresql.org/docs/9.1/app-pgdump.html Next, create a new wallets schema in your local database. Navigate to the database folder and create a database.json file populated with the credentials for your local server: @@ -137,6 +128,7 @@ Next, create a new wallets schema in your local database. Navigate to the databa } } ``` + To quickly build the necessary tables for your wallets schema, run: ``` @@ -151,28 +143,39 @@ If you have not installed db-migrate globally, while in the database folder, you See here to learn more about db-migrate: https://db-migrate.readthedocs.io/en/latest/ -### Setting up env variables +### Setting up env variables in your .env file you have (you can look at env.example) + ``` ... PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\nXXXXXXXXXXXXXXXX\n-----END PUBLIC KEY-----" PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nXXXXXXXXXXXXXXXXXXXXX\n-----END RSA PRIVATE KEY-----" ... ``` -Copy and paste the PUBLIC_KEY and PRIVATE_KEY strings above exactly as is. Then, go to your jwtRS256.key.pub and jwtRS256.key files generated earlier in your config folder and remove all the new lines. Replace the "XXXXX.." with the key codes between the BEGIN PUBLIC KEY and END PUBLIC KEY sections (pasted as a single line) from your respective jwtRS256.key.pub and jwtRS256.key files. **Don't just copy and paste the whole block from these files into these sections since we need to preserve this format with the "\n" injected into the strings here. -## Troubleshooting -If you run into issue: +Copy and paste the PUBLIC_KEY and PRIVATE_KEY strings above exactly as is. Then, go to your jwtRS256.key.pub and jwtRS256.key files generated earlier in your config folder and remove all the new lines. Replace the "XXXXX.." with the key codes between the BEGIN PUBLIC KEY and END PUBLIC KEY sections (pasted as a single line) from your respective jwtRS256.key.pub and jwtRS256.key files. \*\*Don't just copy and paste the whole block from these files into these sections since we need to preserve this format with the "\n" injected into the strings here. + +### We are using linter to keep the project in shape + +if you are using VScode as your IDE, you can set up linter to run on save, which is very handy +you can set it up by going to Preferences > Settings > Workspace > Formatting > Format on Save + +## Troubleshooting + +If you run into issue: + ``` ifError got unwanted exception: function uuid_generate_v4() does not exist ``` + Delete and recreate your wallets schema and then inside your postgres connection in terminal, run to install the required extension ``` -\c +\c CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; ``` + Now re-run the "db-migrate --env dev up" command in your normal terminal in the database directory. Now you should be all set up and ready to go! @@ -181,30 +184,29 @@ Now you should be all set up and ready to go! This project use multiple layer structure to build the whole system. Similar with MVC structure: -![layers](/layers.png "layers") - +![layers](/layers.png 'layers') -* **Protocol layer** +- **Protocol layer** Wallet API offers RESTFul API interace based on HTTP protocol. We use Express to handle all HTTP requests. The Express-routers work like the controller role in MVC, they receive the requests and parameters from client, and translate it and dispatch tasks to appropriate business objects. Then receive the result from them, translate to the 'view', the JSON response, to client. -* **Service layer** +- **Service layer** -Both service layer and model layer are where all the business logic is located. Comparing to the Model , `service` object don't have state (stateless). +Both service layer and model layer are where all the business logic is located. Comparing to the Model , `service` object don't have state (stateless). Please put business logic code into service object when it is hard to put them into the `Model` object. Because we didn't use Factory or dependency injection to create object, so service layer also can be used as Factory to create `model` object. -* **Model layer** +- **Model layer** -The business model, major business logic is here. They are real object, in the perspective of object oriented programming: they have states, they have the method to do stuff. +The business model, major business logic is here. They are real object, in the perspective of object oriented programming: they have states, they have the method to do stuff. There are more discussion about this, check below selection. -* **Repository layer** +- **Repository layer** Repository is responsible for communicate with the real database, this isolation brings flexibility for us, for example, we can consider replace the implementation of the storage infrastructure in the future. @@ -232,9 +234,9 @@ Because we are not using ORM (Object Relationship Mapping) and not using object Thanks Knex, we can use it to easily retrieve objects from SQL DB, but they are simple value object, not model. -So the trade-off way we are using is building model object JUST with the identity (e.g. primary key), but don't have any other properties, if we want to visit them, require the DB(repository) at the moment. +So the trade-off way we are using is building model object JUST with the identity (e.g. primary key), but don't have any other properties, if we want to visit them, require the DB(repository) at the moment. -In some case, to reduce the traffic to the DB, model can cache the JSON object from DB by contructor the model object with it. In this case, the outside code which is using this model should be responsible for keep the cached JSON (in model object) consistent with the DB status. +In some case, to reduce the traffic to the DB, model can cache the JSON object from DB by contructor the model object with it. In this case, the outside code which is using this model should be responsible for keep the cached JSON (in model object) consistent with the DB status. ### Seting up DB transaction @@ -256,7 +258,7 @@ try{ const tokens = []; const tokenService = new TokenService(session); for(let uuid of req.body.tokens){ - const token = await tokenService.getByUUID(uuid); + const token = await tokenService.getByUUID(uuid); tokens.push(token); } result = await walletLogin.transfer(walletSender, walletReceiver, tokens); @@ -268,7 +270,7 @@ try{ if(result.state === Transfer.STATE.completed){ res.status(201).json(result); }else if( - result.state === Transfer.STATE.pending || + result.state === Transfer.STATE.pending || result.state === Transfer.STATE.requested){ res.status(202).json(result); }else{ @@ -291,16 +293,15 @@ try{ By wrapping all the code in a try/catch block, if everything goes well, when the code reach to the line `await session.commitTransaction()`, all those changing happned in this code block would be commited to DB. If somthine went wrong, there are three cases: -1. If this is a unkown error, for example, the DB lib thrown something like: connection to DB is broken, then the transaction would rollback to the start point. +1. If this is a unkown error, for example, the DB lib thrown something like: connection to DB is broken, then the transaction would rollback to the start point. 2. If this is a error thrown by ourselves, we can chose to commit or rollback by setting the flag in HttpError: - ``` throw new HttpError(403, `the token:${json.uuid} do not belongs to sender walleter`, true); ``` -The third parameter `true` means please rollback. (This is the default case for HttpError); +The third parameter `true` means please rollback. (This is the default case for HttpError); 3. If set the HttpError's `toRollback` (the third parameter) to false, then, the transaction would commit anyway. @@ -321,7 +322,7 @@ someService = { } ``` -There are two way to compose object, Class or direct literal object in Javascript, this project we suggest use Class to build object, like: model, service, repository, even though they are stateless objects. This is because generally to say, Class brings more flexibility for future choices, all the things literal object and do, Class can do it too, but literal object can not do all the things Class can do. +There are two way to compose object, Class or direct literal object in Javascript, this project we suggest use Class to build object, like: model, service, repository, even though they are stateless objects. This is because generally to say, Class brings more flexibility for future choices, all the things literal object and do, Class can do it too, but literal object can not do all the things Class can do. One things should be considered in future is the database transaction, if we use Class and create new instance ever time, then it's possible for us to pass the transition session object into the object to do things in a database transaction session. @@ -337,9 +338,9 @@ throw new HttpError(403, 'Do not have permission to do this operation...'); The protocol layer would catch the object and return to client with this response: -* Status code: 403 +- Status code: 403 -* Response body: +- Response body: ``` { @@ -390,7 +391,7 @@ log.debug("..."); log.info("..."); ``` -* The default log level +- The default log level The default log level is `info`, the change it temporarily, when developing, set the env: `NODE_LOG_LEVEL`, for example: @@ -423,6 +424,7 @@ npm run test-integration ``` ## Database seeding test + In order to efficiently run our integration tests, we rely on automated database seeding/clearing functions to mock database entries. To test these functions, run: ``` @@ -503,13 +505,12 @@ Chai is not good for testing/catching errors throwing from internal stack. We ar }).rejects.toThrow(/can not find entity/); ``` - # Contributing Create your local git branch and rebase it from the shared master branch. Please make sure to 1) npm install and 2) delete and rebuild your local database wallet schema using the migrations (as illustrated in the Database Setup section above) to capture any latest updates/changes. Please follow this convention for commit messages [here](https://www.conventionalcommits.org/en/v1.0.0/) -Any developers joining the project should feel free to review any outstanding pull requests and assign themselves to any open tickets on the Issues list. You can make a draft pull request as you are working on any open issue that interests you, and any changes you make on your local branch can be continually synced with this draft until you are ready to submit. Remember to push your changes up to your forked repository and then make any pull requests from your forked branch to the Greenstand master repository branch. +Any developers joining the project should feel free to review any outstanding pull requests and assign themselves to any open tickets on the Issues list. You can make a draft pull request as you are working on any open issue that interests you, and any changes you make on your local branch can be continually synced with this draft until you are ready to submit. Remember to push your changes up to your forked repository and then make any pull requests from your forked branch to the Greenstand master repository branch. -When you are ready to submit a pull request, please rebase your branch off of the shared master branch again to integrate any new updates in the codebase before submitting. +When you are ready to submit a pull request, please rebase your branch off of the shared master branch again to integrate any new updates in the codebase before submitting. diff --git a/__tests__/auth.spec.js b/__tests__/auth.spec.js index 2100fdc8..214a0948 100644 --- a/__tests__/auth.spec.js +++ b/__tests__/auth.spec.js @@ -1,13 +1,13 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); describe('Authentication', () => { diff --git a/__tests__/bundle-transfer-cancel.spec.js b/__tests__/bundle-transfer-cancel.spec.js index 15f32988..f718b6d8 100644 --- a/__tests__/bundle-transfer-cancel.spec.js +++ b/__tests__/bundle-transfer-cancel.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Create and accept a bundle transfer', () => { diff --git a/__tests__/bundle-transfer-create-accept.spec.js b/__tests__/bundle-transfer-create-accept.spec.js index 16f1de84..b339213c 100644 --- a/__tests__/bundle-transfer-create-accept.spec.js +++ b/__tests__/bundle-transfer-create-accept.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Create and accept a bundle transfer', () => { diff --git a/__tests__/bundle-transfer-decline.spec.js b/__tests__/bundle-transfer-decline.spec.js index 885d6d3e..03702b3e 100644 --- a/__tests__/bundle-transfer-decline.spec.js +++ b/__tests__/bundle-transfer-decline.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Create and accept a bundle transfer', () => { diff --git a/__tests__/fulfill-bundle-transfer-request.spec.js b/__tests__/fulfill-bundle-transfer-request.spec.js index 84e5196e..1983af27 100644 --- a/__tests__/fulfill-bundle-transfer-request.spec.js +++ b/__tests__/fulfill-bundle-transfer-request.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Request and fulfill a bundle transfer', () => { diff --git a/__tests__/fulfill-explicity-transfer-request.spec.js b/__tests__/fulfill-explicity-transfer-request.spec.js index f3ca04c4..f2240566 100644 --- a/__tests__/fulfill-explicity-transfer-request.spec.js +++ b/__tests__/fulfill-explicity-transfer-request.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Request and fulfill an explicit transfer', () => { diff --git a/__tests__/get-tokens.spec.js b/__tests__/get-tokens.spec.js index f2d1bd2e..8bd3a714 100644 --- a/__tests__/get-tokens.spec.js +++ b/__tests__/get-tokens.spec.js @@ -1,26 +1,23 @@ /* * The integration test to test the whole business, with DB */ -require('dotenv').config() +require('dotenv').config(); const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); +const sinon = require('sinon'); +const chai = require('chai'); const seed = require('./seed'); -const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); -const sinon = require("sinon"); -const chai = require("chai"); +const server = require('../server/app'); chai.use(require('chai-uuid')); describe('GET tokens', () => { let bearerToken; let bearerTokenB; - before( async () => { - + beforeEach(async () => { await seed.clear(); await seed.seed(); + sinon.restore(); { // Authorizes before each of the follow tests @@ -51,14 +48,10 @@ describe('GET tokens', () => { } }); - beforeEach(async () => { - sinon.restore(); - }) - it(`walletA, GET /tokens/${seed.token.id} Should be able to get a token `, async () => { const res = await request(server) .get(`/tokens/${seed.token.id}`) - .set('treetracker-api-key',seed.apiKey) + .set('treetracker-api-key', seed.apiKey) .set('Authorization', `Bearer ${bearerToken}`); expect(res).to.have.property('statusCode', 200); expect(res.body).to.have.property('id').eq(seed.token.id); @@ -67,7 +60,7 @@ describe('GET tokens', () => { it(`walletA, GET /tokens/${seed.tokenB.id} Should be forbidden`, async () => { const res = await request(server) .get(`/tokens/${seed.tokenB.id}`) - .set('treetracker-api-key',seed.apiKey) + .set('treetracker-api-key', seed.apiKey) .set('Authorization', `Bearer ${bearerToken}`); expect(res).to.have.property('statusCode', 401); }); @@ -75,7 +68,7 @@ describe('GET tokens', () => { it(`walletA, GET /tokens Should be able to get a token `, async () => { const res = await request(server) .get(`/tokens?limit=10`) - .set('treetracker-api-key',seed.apiKey) + .set('treetracker-api-key', seed.apiKey) .set('Authorization', `Bearer ${bearerToken}`); expect(res).to.have.property('statusCode', 200); expect(res.body.tokens[0]).to.have.property('id').eq(seed.token.id); @@ -84,7 +77,7 @@ describe('GET tokens', () => { it(`walletB, GET /tokens Should be able to get a token, which actually belongs to walletC`, async () => { const res = await request(server) .get(`/tokens?limit=10&wallet=walletC`) - .set('treetracker-api-key',seed.apiKey) + .set('treetracker-api-key', seed.apiKey) .set('Authorization', `Bearer ${bearerTokenB}`); expect(res).to.have.property('statusCode', 200); expect(res.body.tokens[0]).to.have.property('id').eq(seed.tokenB.id); @@ -93,9 +86,32 @@ describe('GET tokens', () => { it(`walletB, GET /tokens/${seed.tokenB.id} Should be able to get a token `, async () => { const res = await request(server) .get(`/tokens/${seed.tokenB.id}`) - .set('treetracker-api-key',seed.apiKey) + .set('treetracker-api-key', seed.apiKey) .set('Authorization', `Bearer ${bearerTokenB}`); expect(res).to.have.property('statusCode', 200); expect(res.body).to.have.property('id').eq(seed.tokenB.id); }); + it(`GET /tokens/ should return correct limit`, async () => { + await seed.addTokenToWallet(seed.wallet.id); + const res = await request(server) + .get(`/tokens?limit=1`) + .set('treetracker-api-key', seed.apiKey) + .set('Authorization', `Bearer ${bearerToken}`); + + expect(res).to.have.property('statusCode', 200); + expect(res.body.tokens.length).to.eq(1); + expect(res.body.tokens[0].id).eq(seed.token.id); + }); + + it(`GET /tokens/ should return correct offset`, async () => { + const insertedId = (await seed.addTokenToWallet(seed.wallet.id))[0].id; + const res = await request(server) + .get(`/tokens?offset=1&limit=10`) + .set('treetracker-api-key', seed.apiKey) + .set('Authorization', `Bearer ${bearerToken}`); + + expect(res).to.have.property('statusCode', 200); + expect(res.body.tokens.length).to.eq(1); + expect(res.body.tokens[0].id).eq(insertedId); + }); }); diff --git a/__tests__/integration/auth.spec.js b/__tests__/integration/auth.spec.js index 1f19d965..5849f4ac 100644 --- a/__tests__/integration/auth.spec.js +++ b/__tests__/integration/auth.spec.js @@ -1,10 +1,10 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../../server/app"); const { expect } = require('chai'); const log = require('loglevel'); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../../server/app"); chai.use(require('chai-uuid')); const Zaven = require("../mock-data/Zaven.json"); const testUtils = require("./testUtils"); diff --git a/__tests__/integration/bundle-transfer-decline.spec.js b/__tests__/integration/bundle-transfer-decline.spec.js index cd79a4d7..f2b444f8 100644 --- a/__tests__/integration/bundle-transfer-decline.spec.js +++ b/__tests__/integration/bundle-transfer-decline.spec.js @@ -1,9 +1,9 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../../server/app"); const { expect } = require('chai'); const log = require('loglevel'); const chai = require("chai"); +const server = require("../../server/app"); chai.use(require('chai-uuid')); const Zaven = require("../mock-data/Zaven.json"); const Meisze = require("../mock-data/Meisze.json"); diff --git a/__tests__/integration/testUtils.js b/__tests__/integration/testUtils.js index 8488ae6c..6255fae4 100644 --- a/__tests__/integration/testUtils.js +++ b/__tests__/integration/testUtils.js @@ -1,24 +1,24 @@ -const knex = require("../../server/database/knex"); const uuid = require('uuid'); const log = require("loglevel"); const Crypto = require('crypto'); const generator = require('generate-password'); +const { expect } = require('chai'); const JWTService = require("../../server/services/JWTService"); const Transfer = require("../../server/models/Transfer"); -const { expect } = require('chai'); +const knex = require("../../server/database/knex"); /* * register the user, create password hash, and apiKey */ async function register(user){ const sha512 = function(password, salt){ - var hash = Crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ + const hash = Crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ hash.update(password); - var value = hash.digest('hex'); + const value = hash.digest('hex'); return value; }; - const salt = Crypto.randomBytes(32).toString('base64') //create a secure salt + const salt = Crypto.randomBytes(32).toString('base64') // create a secure salt const passwordHash = sha512(user.password, salt) const apiKey = generator.generate({ @@ -41,13 +41,13 @@ async function register(user){ id: uuid.v4(), name: user.name, password: passwordHash, - salt: salt, + salt, }).returning("*"); log.info("registered wallet:", result); return { ...result[0], apiKey, - //restore password + // restore password password: user.password, }; } diff --git a/__tests__/pending-transfer-cancel.spec.js b/__tests__/pending-transfer-cancel.spec.js index 1c67fc9c..9db0927b 100644 --- a/__tests__/pending-transfer-cancel.spec.js +++ b/__tests__/pending-transfer-cancel.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Create and cancel a pending transfer', () => { let bearerToken; diff --git a/__tests__/pending-transfer-decline.spec.js b/__tests__/pending-transfer-decline.spec.js index 9cb4203d..7c750a2a 100644 --- a/__tests__/pending-transfer-decline.spec.js +++ b/__tests__/pending-transfer-decline.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Create and decline a pending transfer', () => { let bearerToken; diff --git a/__tests__/pending-transfer-wrong-wallet.spec.js b/__tests__/pending-transfer-wrong-wallet.spec.js index 7613adad..beb7fa79 100644 --- a/__tests__/pending-transfer-wrong-wallet.spec.js +++ b/__tests__/pending-transfer-wrong-wallet.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Create and fail to accept a pending transfer with wrong wallet', () => { let bearerToken; diff --git a/__tests__/pending-transfer.spec.js b/__tests__/pending-transfer.spec.js index e10ddc4a..b1db3490 100644 --- a/__tests__/pending-transfer.spec.js +++ b/__tests__/pending-transfer.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Create and accept a pending transfer', () => { let bearerToken; diff --git a/__tests__/seed.js b/__tests__/seed.js index 29e04971..f6c041e6 100644 --- a/__tests__/seed.js +++ b/__tests__/seed.js @@ -86,7 +86,7 @@ storyOfThisSeed, async function seed() { log.debug('seed api key'); - //TODO should use appropriate hash & salt to populate this table + // TODO should use appropriate hash & salt to populate this table await knex('api_key') .insert({ key: apiKey, @@ -105,7 +105,7 @@ async function seed() { salt: wallet.salt, }); - //walletB + // walletB await knex('wallet') .insert({ id: walletB.id, @@ -114,7 +114,7 @@ async function seed() { salt: walletB.salt, }); - //walletC + // walletC await knex('wallet') .insert({ id: walletC.id, @@ -123,7 +123,7 @@ async function seed() { salt: walletC.salt, }); - //relationships: 'walletB' manage 'walletC' + // relationships: 'walletB' manage 'walletC' await knex('wallet_trust') .insert({ type: "manage", @@ -147,6 +147,15 @@ async function seed() { .insert(tokenB); } +async function addTokenToWallet(walletId){ + return await knex('token') + .insert({ + id: uuid.v4(), + capture_id: uuid.v4(), + wallet_id: walletId, + }, ['id']); +} + async function clear() { log.debug('clear tables'); await knex('api_key').del(); @@ -168,4 +177,5 @@ module.exports = { token, tokenB, captureB, + addTokenToWallet }; diff --git a/__tests__/seed.spec.js b/__tests__/seed.spec.js index b4819deb..9521a00c 100644 --- a/__tests__/seed.spec.js +++ b/__tests__/seed.spec.js @@ -1,7 +1,7 @@ -const seed = require("./seed"); const {expect} = require("chai"); const Crypto = require('crypto'); const log = require("loglevel"); +const seed = require("./seed"); const knex = require("../server/database/knex"); describe("Seed data into DB", () => { diff --git a/__tests__/session.spec.js b/__tests__/session.spec.js index 466af2da..694e3ceb 100644 --- a/__tests__/session.spec.js +++ b/__tests__/session.spec.js @@ -1,19 +1,20 @@ /* * Test session mechanism */ -const seed = require('./seed'); -const Session = require("../server/models/Session"); const jestExpect = require("expect"); const sinon = require("sinon"); const chai = require("chai"); const sinonChai = require("sinon-chai"); +const Session = require("../server/models/Session"); +const seed = require('./seed'); + chai.use(sinonChai); const {expect} = chai; describe("Session integration", () => { beforeEach(async () => { - //before all, seed data to DB + // before all, seed data to DB await seed.clear(); await seed.seed(); diff --git a/__tests__/trust-relationship-api.spec.js b/__tests__/trust-relationship-api.spec.js index 19c772c0..53142a5f 100644 --- a/__tests__/trust-relationship-api.spec.js +++ b/__tests__/trust-relationship-api.spec.js @@ -1,26 +1,24 @@ -require('dotenv').config() +require('dotenv').config(); const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); -const sinon = require("sinon"); -const chai = require("chai"); +const sinon = require('sinon'); +const chai = require('chai'); +const server = require('../server/app'); +const seed = require('./seed'); +const Transfer = require('../server/models/Transfer'); +const TrustRelationship = require('../server/models/TrustRelationship'); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const { apiKey } = seed; describe('Trust relationship management', () => { - let bearerToken; let bearerTokenB; let bearerTokenC; let trustRelationshipId; - before( async () => { - + before(async () => { await seed.clear(); await seed.seed(); @@ -69,123 +67,121 @@ describe('Trust relationship management', () => { beforeEach(async () => { sinon.restore(); - }) - + }); - it("Creates send relationship", async () => { + it('Creates send relationship', async () => { const res = await request(server) - .post("/trust_relationships") + .post('/trust_relationships') .set('treetracker-api-key', apiKey) .set('Authorization', `Bearer ${bearerToken}`) .send({ trust_request_type: 'send', requestee_wallet: seed.walletC.name, }); - expect(res).property("statusCode").to.eq(200); + expect(res).property('statusCode').to.eq(200); }); - it("GET /trust_relationships", async () => { + it('GET /trust_relationships', async () => { const res = await request(server) - .get("/trust_relationships") + .get('/trust_relationships') .set('treetracker-api-key', apiKey) .set('Authorization', `Bearer ${bearerToken}`); - expect(res).property("statusCode").to.eq(200); // Integration - expect(res).property("body").property("trust_relationships").lengthOf(1); // Integration - expect(res.body.trust_relationships[0]).property("id").to.be.a.uuid('v4') // Unit test, or use Joi to evaluate entire payload + expect(res).property('statusCode').to.eq(200); // Integration + expect(res).property('body').property('trust_relationships').lengthOf(1); // Integration + expect(res.body.trust_relationships[0]).property('id').to.be.a.uuid('v4'); // Unit test, or use Joi to evaluate entire payload }); - it("POST /trust_relationships with wrong request type", async () => { + it('POST /trust_relationships with wrong request type', async () => { const res = await request(server) - .post("/trust_relationships") + .post('/trust_relationships') .set('treetracker-api-key', apiKey) .set('Authorization', `Bearer ${bearerToken}`) .send({ trust_request_type: 'wrongtype', wallet: 'any', }); - expect(res).property("statusCode").to.eq(422); + expect(res).property('statusCode').to.eq(422); }); - it("POST /trust_relationships", async () => { + it('POST /trust_relationships', async () => { const res = await request(server) - .post("/trust_relationships") + .post('/trust_relationships') .set('treetracker-api-key', apiKey) .set('Authorization', `Bearer ${bearerToken}`) .send({ trust_request_type: 'send', requestee_wallet: seed.walletB.name, }); - console.log(res.body) - expect(res).property("statusCode").to.eq(200); + console.log(res.body); + expect(res).property('statusCode').to.eq(200); }); it(`${seed.walletB.name} try to request "manage" relationship to ${seed.wallet.name}`, async () => { await seed.clear(); await seed.seed(); - let res = await request(server) - .post("/trust_relationships") + const res = await request(server) + .post('/trust_relationships') .set('treetracker-api-key', apiKey) .set('Authorization', `Bearer ${bearerTokenB}`) .send({ trust_request_type: 'manage', requestee_wallet: seed.wallet.name, }); - console.log('ww') - console.log(res.body) - expect(res).property("statusCode").to.eq(200); - trustRelationship = res.body; - expect(trustRelationship).property("id").to.be.a.uuid('v4') - expect(trustRelationship).property("state").eq(TrustRelationship.ENTITY_TRUST_STATE_TYPE.requested); + console.log('ww'); + console.log(res.body); + expect(res).property('statusCode').to.eq(200); + const trustRelationship = res.body; + expect(trustRelationship).property('id').to.be.a.uuid('v4'); + expect(trustRelationship) + .property('state') + .eq(TrustRelationship.ENTITY_TRUST_STATE_TYPE.requested); trustRelationshipId = trustRelationship.id; - }) + }); it(`${seed.wallet.name} accept this request`, async () => { const res = await request(server) .post(`/trust_relationships/${trustRelationshipId}/accept`) - .set('Content-Type', "application/json") + .set('Content-Type', 'application/json') .set('treetracker-api-key', apiKey) .set('Authorization', `Bearer ${bearerToken}`); - expect(res).property("statusCode").to.eq(200); - expect(res.body).property("state").eq("trusted"); - expect(res.body).property("type").eq("manage"); - expect(res.body).property("actor_wallet").eq(seed.walletB.name); - expect(res.body).property("target_wallet").eq(seed.wallet.name); + expect(res).property('statusCode').to.eq(200); + expect(res.body).property('state').eq('trusted'); + expect(res.body).property('type').eq('manage'); + expect(res.body).property('actor_wallet').eq(seed.walletB.name); + expect(res.body).property('target_wallet').eq(seed.wallet.name); }); it(`${seed.walletB.name} try to request "yield" relationship to ${seed.wallet.name}`, async () => { await seed.clear(); await seed.seed(); - res = await request(server) - .post("/trust_relationships") + const res = await request(server) + .post('/trust_relationships') .set('treetracker-api-key', apiKey) .set('Authorization', `Bearer ${bearerTokenB}`) .send({ trust_request_type: 'yield', requestee_wallet: seed.wallet.name, }); - expect(res).property("statusCode").to.eq(200); - trustRelationship = res.body; - expect(trustRelationship).property("id").to.be.a.uuid('v4'); - expect(trustRelationship).property("state").eq(TrustRelationship.ENTITY_TRUST_STATE_TYPE.requested); + expect(res).property('statusCode').to.eq(200); + const trustRelationship = res.body; + expect(trustRelationship).property('id').to.be.a.uuid('v4'); + expect(trustRelationship) + .property('state') + .eq(TrustRelationship.ENTITY_TRUST_STATE_TYPE.requested); trustRelationshipId = trustRelationship.id; - }) + }); it(`${seed.wallet.name} accept yeild request`, async () => { const res = await request(server) .post(`/trust_relationships/${trustRelationshipId}/accept`) - .set('Content-Type', "application/json") + .set('Content-Type', 'application/json') .set('treetracker-api-key', apiKey) .set('Authorization', `Bearer ${bearerToken}`); - expect(res).property("statusCode").to.eq(200); - expect(res.body).property("state").eq("trusted"); - expect(res.body).property("type").eq("manage"); - expect(res.body).property("actor_wallet").eq(seed.walletB.name); - expect(res.body).property("target_wallet").eq(seed.wallet.name); + expect(res).property('statusCode').to.eq(200); + expect(res.body).property('state').eq('trusted'); + expect(res.body).property('type').eq('manage'); + expect(res.body).property('actor_wallet').eq(seed.walletB.name); + expect(res.body).property('target_wallet').eq(seed.wallet.name); }); }); - - - - - diff --git a/__tests__/trust-relationship-manage.spec.js b/__tests__/trust-relationship-manage.spec.js index bffda97b..ab2c16cd 100644 --- a/__tests__/trust-relationship-manage.spec.js +++ b/__tests__/trust-relationship-manage.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Trust relationship: manage', () => { diff --git a/__tests__/trust-relationship-send-cancel.spec.js b/__tests__/trust-relationship-send-cancel.spec.js index cd517302..7b8f8ee4 100644 --- a/__tests__/trust-relationship-send-cancel.spec.js +++ b/__tests__/trust-relationship-send-cancel.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Trust relationship: decline send', () => { let bearerToken; diff --git a/__tests__/trust-relationship-send-decline.spec.js b/__tests__/trust-relationship-send-decline.spec.js index cc43a983..f3f10b2c 100644 --- a/__tests__/trust-relationship-send-decline.spec.js +++ b/__tests__/trust-relationship-send-decline.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Trust relationship: decline send', () => { let bearerToken; diff --git a/__tests__/trust-relationship-send.spec.js b/__tests__/trust-relationship-send.spec.js index 7987495e..7ad4ccf0 100644 --- a/__tests__/trust-relationship-send.spec.js +++ b/__tests__/trust-relationship-send.spec.js @@ -1,16 +1,16 @@ require('dotenv').config() const request = require('supertest'); -const server = require("../server/app"); const { expect } = require('chai'); -const seed = require('./seed'); const log = require('loglevel'); -const Transfer = require("../server/models/Transfer"); -const TrustRelationship = require("../server/models/TrustRelationship"); const sinon = require("sinon"); const chai = require("chai"); +const server = require("../server/app"); +const seed = require('./seed'); +const Transfer = require("../server/models/Transfer"); +const TrustRelationship = require("../server/models/TrustRelationship"); chai.use(require('chai-uuid')); -const apiKey = seed.apiKey; +const {apiKey} = seed; describe('Trust relationship: send', () => { let bearerToken; diff --git a/database/migrations/20200826045032-CreateSchemaWallets.js b/database/migrations/20200826045032-CreateSchemaWallets.js index eaf38385..5cc583e5 100644 --- a/database/migrations/20200826045032-CreateSchemaWallets.js +++ b/database/migrations/20200826045032-CreateSchemaWallets.js @@ -1,29 +1,27 @@ -'use strict'; - -var dbm; -var type; -var seed; +let dbm; +let type; +let seed; /** - * We receive the dbmigrate dependency from dbmigrate initially. - * This enables us to not have to rely on NODE_PATH. - */ -exports.setup = function(options, seedLink) { + * We receive the dbmigrate dependency from dbmigrate initially. + * This enables us to not have to rely on NODE_PATH. + */ +exports.setup = function (options, seedLink) { dbm = options.dbmigrate; type = dbm.dataType; seed = seedLink; }; -exports.up = function(db) { +exports.up = function (db) { return null; - return db.runSql("CREATE SCHEMA wallets"); + // return db.runSql("CREATE SCHEMA wallets"); }; -exports.down = function(db) { +exports.down = function (db) { return null; - return db.runSql("DROP SCHEMA wallets"); + // return db.runSql("DROP SCHEMA wallets"); }; exports._meta = { - "version": 1 + version: 1, }; diff --git a/database/migrations/20200826045033-AddUUIDExtension.js b/database/migrations/20200826045033-AddUUIDExtension.js index 4e864626..2cf78c82 100644 --- a/database/migrations/20200826045033-AddUUIDExtension.js +++ b/database/migrations/20200826045033-AddUUIDExtension.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. @@ -19,7 +19,7 @@ exports.up = function(db) { }; exports.down = function(db, done) { - //return db.runSql('DROP EXTENSION "uuid-ossp"'); + // return db.runSql('DROP EXTENSION "uuid-ossp"'); done() }; diff --git a/database/migrations/20200826045033-CreateTableTransaction.js b/database/migrations/20200826045033-CreateTableTransaction.js index 2ceb73b3..f186e520 100644 --- a/database/migrations/20200826045033-CreateTableTransaction.js +++ b/database/migrations/20200826045033-CreateTableTransaction.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200830050917-CreateEnumTransferState.js b/database/migrations/20200830050917-CreateEnumTransferState.js index 5ac990a7..e197dc0f 100644 --- a/database/migrations/20200830050917-CreateEnumTransferState.js +++ b/database/migrations/20200830050917-CreateEnumTransferState.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200830050921-CreateEnumTransferType.js b/database/migrations/20200830050921-CreateEnumTransferType.js index 3a0c099e..0ba19542 100644 --- a/database/migrations/20200830050921-CreateEnumTransferType.js +++ b/database/migrations/20200830050921-CreateEnumTransferType.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200901213040-CreateEnumEntityTrustReqType.js b/database/migrations/20200901213040-CreateEnumEntityTrustReqType.js index 467d5562..20bedb19 100644 --- a/database/migrations/20200901213040-CreateEnumEntityTrustReqType.js +++ b/database/migrations/20200901213040-CreateEnumEntityTrustReqType.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200901213111-CreateEnumEntityTrustType.js b/database/migrations/20200901213111-CreateEnumEntityTrustType.js index 4d03849d..d822a516 100644 --- a/database/migrations/20200901213111-CreateEnumEntityTrustType.js +++ b/database/migrations/20200901213111-CreateEnumEntityTrustType.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200901213222-CreateEnumEntityTrustStateType.js b/database/migrations/20200901213222-CreateEnumEntityTrustStateType.js index 585b3341..63232f43 100644 --- a/database/migrations/20200901213222-CreateEnumEntityTrustStateType.js +++ b/database/migrations/20200901213222-CreateEnumEntityTrustStateType.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200901213241-CreateEnumTransferStateChangeApprovalType.js b/database/migrations/20200901213241-CreateEnumTransferStateChangeApprovalType.js index f05c8278..97c098e8 100644 --- a/database/migrations/20200901213241-CreateEnumTransferStateChangeApprovalType.js +++ b/database/migrations/20200901213241-CreateEnumTransferStateChangeApprovalType.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200901213252-CreateEnumWalletEventType.js b/database/migrations/20200901213252-CreateEnumWalletEventType.js index 0a63b356..e2dcc08b 100644 --- a/database/migrations/20200901213252-CreateEnumWalletEventType.js +++ b/database/migrations/20200901213252-CreateEnumWalletEventType.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200901213253-CreateTableToken.js b/database/migrations/20200901213253-CreateTableToken.js index b3ffd0d7..ffbcd141 100644 --- a/database/migrations/20200901213253-CreateTableToken.js +++ b/database/migrations/20200901213253-CreateTableToken.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200901213254-CreateTableTransfer.js b/database/migrations/20200901213254-CreateTableTransfer.js index 4df57f1a..b6edb1cd 100644 --- a/database/migrations/20200901213254-CreateTableTransfer.js +++ b/database/migrations/20200901213254-CreateTableTransfer.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200901222910-CreateTableWallet-Event.js b/database/migrations/20200901222910-CreateTableWallet-Event.js index b7a7a90c..89ddd7ae 100644 --- a/database/migrations/20200901222910-CreateTableWallet-Event.js +++ b/database/migrations/20200901222910-CreateTableWallet-Event.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200902014751-CreateTableEntity-Trust.js b/database/migrations/20200902014751-CreateTableEntity-Trust.js index 78b56ffe..f46efc81 100644 --- a/database/migrations/20200902014751-CreateTableEntity-Trust.js +++ b/database/migrations/20200902014751-CreateTableEntity-Trust.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200902014758-CreateTableEntity-Trust-Log.js b/database/migrations/20200902014758-CreateTableEntity-Trust-Log.js index 1782e274..3d0d6eeb 100644 --- a/database/migrations/20200902014758-CreateTableEntity-Trust-Log.js +++ b/database/migrations/20200902014758-CreateTableEntity-Trust-Log.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200902014805-CreateTableTransfer-Audit.js b/database/migrations/20200902014805-CreateTableTransfer-Audit.js index 2c0ada54..ae06d7e5 100644 --- a/database/migrations/20200902014805-CreateTableTransfer-Audit.js +++ b/database/migrations/20200902014805-CreateTableTransfer-Audit.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200916235257-CreateTableApi-Key.js b/database/migrations/20200916235257-CreateTableApi-Key.js index a567cbb1..9c3a7c85 100644 --- a/database/migrations/20200916235257-CreateTableApi-Key.js +++ b/database/migrations/20200916235257-CreateTableApi-Key.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20200917183542-CreateTableWallet.js b/database/migrations/20200917183542-CreateTableWallet.js index 0003f500..8b6a897c 100644 --- a/database/migrations/20200917183542-CreateTableWallet.js +++ b/database/migrations/20200917183542-CreateTableWallet.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20201127234338-AllowNullPasswordWallet.js b/database/migrations/20201127234338-AllowNullPasswordWallet.js index a01a7e4f..7031afa1 100644 --- a/database/migrations/20201127234338-AllowNullPasswordWallet.js +++ b/database/migrations/20201127234338-AllowNullPasswordWallet.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20201209064928-RenameTableEntityTrust.js b/database/migrations/20201209064928-RenameTableEntityTrust.js index 05ade637..91343042 100644 --- a/database/migrations/20201209064928-RenameTableEntityTrust.js +++ b/database/migrations/20201209064928-RenameTableEntityTrust.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20201209065300-RenameTableEntityTrustLog.js b/database/migrations/20201209065300-RenameTableEntityTrustLog.js index 57e3e5e8..d7935875 100644 --- a/database/migrations/20201209065300-RenameTableEntityTrustLog.js +++ b/database/migrations/20201209065300-RenameTableEntityTrustLog.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20210211020241-AddDefaultIdTransactionTable.js b/database/migrations/20210211020241-AddDefaultIdTransactionTable.js index 2ba0c1d4..463063dd 100644 --- a/database/migrations/20210211020241-AddDefaultIdTransactionTable.js +++ b/database/migrations/20210211020241-AddDefaultIdTransactionTable.js @@ -1,11 +1,12 @@ -'use strict'; -var dbm; -var type; -var seed; -var fs = require('fs'); -var path = require('path'); -var Promise; + +let dbm; +let type; +let seed; +const fs = require('fs'); +const path = require('path'); + +let Promise; /** * We receive the dbmigrate dependency from dbmigrate initially. @@ -19,11 +20,11 @@ exports.setup = function(options, seedLink) { }; exports.up = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020241-AddDefaultIdTransactionTable-up.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020241-AddDefaultIdTransactionTable-up.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); @@ -34,11 +35,11 @@ exports.up = function(db) { }; exports.down = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020241-AddDefaultIdTransactionTable-down.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020241-AddDefaultIdTransactionTable-down.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); diff --git a/database/migrations/20210211020257-AddDefaultIdTransferTable.js b/database/migrations/20210211020257-AddDefaultIdTransferTable.js index 92f08f47..7306a89e 100644 --- a/database/migrations/20210211020257-AddDefaultIdTransferTable.js +++ b/database/migrations/20210211020257-AddDefaultIdTransferTable.js @@ -1,11 +1,12 @@ -'use strict'; -var dbm; -var type; -var seed; -var fs = require('fs'); -var path = require('path'); -var Promise; + +let dbm; +let type; +let seed; +const fs = require('fs'); +const path = require('path'); + +let Promise; /** * We receive the dbmigrate dependency from dbmigrate initially. @@ -19,11 +20,11 @@ exports.setup = function(options, seedLink) { }; exports.up = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020257-AddDefaultIdTransferTable-up.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020257-AddDefaultIdTransferTable-up.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); @@ -34,11 +35,11 @@ exports.up = function(db) { }; exports.down = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020257-AddDefaultIdTransferTable-down.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020257-AddDefaultIdTransferTable-down.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); diff --git a/database/migrations/20210211020301-AddDefaultIdTokenTable.js b/database/migrations/20210211020301-AddDefaultIdTokenTable.js index e8b321ae..179a0418 100644 --- a/database/migrations/20210211020301-AddDefaultIdTokenTable.js +++ b/database/migrations/20210211020301-AddDefaultIdTokenTable.js @@ -1,11 +1,12 @@ -'use strict'; -var dbm; -var type; -var seed; -var fs = require('fs'); -var path = require('path'); -var Promise; + +let dbm; +let type; +let seed; +const fs = require('fs'); +const path = require('path'); + +let Promise; /** * We receive the dbmigrate dependency from dbmigrate initially. @@ -19,11 +20,11 @@ exports.setup = function(options, seedLink) { }; exports.up = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020301-AddDefaultIdTokenTable-up.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020301-AddDefaultIdTokenTable-up.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); @@ -34,11 +35,11 @@ exports.up = function(db) { }; exports.down = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020301-AddDefaultIdTokenTable-down.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020301-AddDefaultIdTokenTable-down.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); diff --git a/database/migrations/20210211020304-AddDefaultIdWalletTable.js b/database/migrations/20210211020304-AddDefaultIdWalletTable.js index 5013f3ab..2cb4db92 100644 --- a/database/migrations/20210211020304-AddDefaultIdWalletTable.js +++ b/database/migrations/20210211020304-AddDefaultIdWalletTable.js @@ -1,11 +1,12 @@ -'use strict'; -var dbm; -var type; -var seed; -var fs = require('fs'); -var path = require('path'); -var Promise; + +let dbm; +let type; +let seed; +const fs = require('fs'); +const path = require('path'); + +let Promise; /** * We receive the dbmigrate dependency from dbmigrate initially. @@ -19,11 +20,11 @@ exports.setup = function(options, seedLink) { }; exports.up = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020304-AddDefaultIdWalletTable-up.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020304-AddDefaultIdWalletTable-up.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); @@ -34,11 +35,11 @@ exports.up = function(db) { }; exports.down = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020304-AddDefaultIdWalletTable-down.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020304-AddDefaultIdWalletTable-down.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); diff --git a/database/migrations/20210211020331-AddDefaultIdApiKeyTable.js b/database/migrations/20210211020331-AddDefaultIdApiKeyTable.js index e1d06760..ec30345d 100644 --- a/database/migrations/20210211020331-AddDefaultIdApiKeyTable.js +++ b/database/migrations/20210211020331-AddDefaultIdApiKeyTable.js @@ -1,11 +1,12 @@ -'use strict'; -var dbm; -var type; -var seed; -var fs = require('fs'); -var path = require('path'); -var Promise; + +let dbm; +let type; +let seed; +const fs = require('fs'); +const path = require('path'); + +let Promise; /** * We receive the dbmigrate dependency from dbmigrate initially. @@ -19,11 +20,11 @@ exports.setup = function(options, seedLink) { }; exports.up = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020331-AddDefaultIdApiKeyTable-up.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020331-AddDefaultIdApiKeyTable-up.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); @@ -34,11 +35,11 @@ exports.up = function(db) { }; exports.down = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020331-AddDefaultIdApiKeyTable-down.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020331-AddDefaultIdApiKeyTable-down.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); diff --git a/database/migrations/20210211020340-AddDefaultIdTransferAuditTable.js b/database/migrations/20210211020340-AddDefaultIdTransferAuditTable.js index 6c5759ef..3588ffc4 100644 --- a/database/migrations/20210211020340-AddDefaultIdTransferAuditTable.js +++ b/database/migrations/20210211020340-AddDefaultIdTransferAuditTable.js @@ -1,11 +1,12 @@ -'use strict'; -var dbm; -var type; -var seed; -var fs = require('fs'); -var path = require('path'); -var Promise; + +let dbm; +let type; +let seed; +const fs = require('fs'); +const path = require('path'); + +let Promise; /** * We receive the dbmigrate dependency from dbmigrate initially. @@ -19,11 +20,11 @@ exports.setup = function(options, seedLink) { }; exports.up = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020340-AddDefaultIdTransferAuditTable-up.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020340-AddDefaultIdTransferAuditTable-up.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); @@ -34,11 +35,11 @@ exports.up = function(db) { }; exports.down = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020340-AddDefaultIdTransferAuditTable-down.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020340-AddDefaultIdTransferAuditTable-down.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); diff --git a/database/migrations/20210211020347-AddDefaultIdWalletEventTable.js b/database/migrations/20210211020347-AddDefaultIdWalletEventTable.js index ac9db7e3..3267ee3d 100644 --- a/database/migrations/20210211020347-AddDefaultIdWalletEventTable.js +++ b/database/migrations/20210211020347-AddDefaultIdWalletEventTable.js @@ -1,11 +1,12 @@ -'use strict'; -var dbm; -var type; -var seed; -var fs = require('fs'); -var path = require('path'); -var Promise; + +let dbm; +let type; +let seed; +const fs = require('fs'); +const path = require('path'); + +let Promise; /** * We receive the dbmigrate dependency from dbmigrate initially. @@ -19,11 +20,11 @@ exports.setup = function(options, seedLink) { }; exports.up = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020347-AddDefaultIdWalletEventTable-up.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020347-AddDefaultIdWalletEventTable-up.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); @@ -34,11 +35,11 @@ exports.up = function(db) { }; exports.down = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020347-AddDefaultIdWalletEventTable-down.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020347-AddDefaultIdWalletEventTable-down.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); diff --git a/database/migrations/20210211020352-AddDefaultIdWalletTrustTable.js b/database/migrations/20210211020352-AddDefaultIdWalletTrustTable.js index 1983f4f8..f6a06654 100644 --- a/database/migrations/20210211020352-AddDefaultIdWalletTrustTable.js +++ b/database/migrations/20210211020352-AddDefaultIdWalletTrustTable.js @@ -1,11 +1,12 @@ -'use strict'; -var dbm; -var type; -var seed; -var fs = require('fs'); -var path = require('path'); -var Promise; + +let dbm; +let type; +let seed; +const fs = require('fs'); +const path = require('path'); + +let Promise; /** * We receive the dbmigrate dependency from dbmigrate initially. @@ -19,11 +20,11 @@ exports.setup = function(options, seedLink) { }; exports.up = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020352-AddDefaultIdWalletTrustTable-up.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020352-AddDefaultIdWalletTrustTable-up.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); @@ -34,11 +35,11 @@ exports.up = function(db) { }; exports.down = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020352-AddDefaultIdWalletTrustTable-down.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020352-AddDefaultIdWalletTrustTable-down.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); diff --git a/database/migrations/20210211020356-AddDefaultIdWalletTrustLogTable.js b/database/migrations/20210211020356-AddDefaultIdWalletTrustLogTable.js index 59260c98..ccf0d92c 100644 --- a/database/migrations/20210211020356-AddDefaultIdWalletTrustLogTable.js +++ b/database/migrations/20210211020356-AddDefaultIdWalletTrustLogTable.js @@ -1,11 +1,12 @@ -'use strict'; -var dbm; -var type; -var seed; -var fs = require('fs'); -var path = require('path'); -var Promise; + +let dbm; +let type; +let seed; +const fs = require('fs'); +const path = require('path'); + +let Promise; /** * We receive the dbmigrate dependency from dbmigrate initially. @@ -19,11 +20,11 @@ exports.setup = function(options, seedLink) { }; exports.up = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020356-AddDefaultIdWalletTrustLogTable-up.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020356-AddDefaultIdWalletTrustLogTable-up.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); @@ -34,11 +35,11 @@ exports.up = function(db) { }; exports.down = function(db) { - var filePath = path.join(__dirname, 'sqls', '20210211020356-AddDefaultIdWalletTrustLogTable-down.sql'); + const filePath = path.join(__dirname, 'sqls', '20210211020356-AddDefaultIdWalletTrustLogTable-down.sql'); return new Promise( function( resolve, reject ) { fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (err) return reject(err); - console.log('received data: ' + data); + console.log(`received data: ${ data}`); resolve(data); }); diff --git a/database/migrations/20210226234313-AddUniqueConstraintWalletName.js b/database/migrations/20210226234313-AddUniqueConstraintWalletName.js index b137b191..7aff616c 100644 --- a/database/migrations/20210226234313-AddUniqueConstraintWalletName.js +++ b/database/migrations/20210226234313-AddUniqueConstraintWalletName.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20210304014730-AddUniqueConstraintCaptureId.js b/database/migrations/20210304014730-AddUniqueConstraintCaptureId.js index 302cf643..f3e0408b 100644 --- a/database/migrations/20210304014730-AddUniqueConstraintCaptureId.js +++ b/database/migrations/20210304014730-AddUniqueConstraintCaptureId.js @@ -1,8 +1,8 @@ -'use strict'; -var dbm; -var type; -var seed; + +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/database/migrations/20210401005831-AddClaimBoolean.js b/database/migrations/20210401005831-AddClaimBoolean.js index f7b3e019..b764d68f 100644 --- a/database/migrations/20210401005831-AddClaimBoolean.js +++ b/database/migrations/20210401005831-AddClaimBoolean.js @@ -1,4 +1,4 @@ -'use strict'; +// 'use strict'; let dbm; let type; diff --git a/database/migrations/20210401015411-AddColClaimBooleanTransferTable.js b/database/migrations/20210401015411-AddColClaimBooleanTransferTable.js index fed66c64..f246075d 100644 --- a/database/migrations/20210401015411-AddColClaimBooleanTransferTable.js +++ b/database/migrations/20210401015411-AddColClaimBooleanTransferTable.js @@ -1,4 +1,4 @@ -'use strict'; +// 'use strict'; let dbm; let type; diff --git a/database/migrations/20210419015057-AddColClaimBooleanTransactionTable.js b/database/migrations/20210419015057-AddColClaimBooleanTransactionTable.js index e2ca64b6..ac40bc94 100644 --- a/database/migrations/20210419015057-AddColClaimBooleanTransactionTable.js +++ b/database/migrations/20210419015057-AddColClaimBooleanTransactionTable.js @@ -1,8 +1,8 @@ -'use strict'; +// 'use strict'; -var dbm; -var type; -var seed; +let dbm; +let type; +let seed; /** * We receive the dbmigrate dependency from dbmigrate initially. diff --git a/docs/api/spec/treetracker-token-api.yaml b/docs/api/spec/treetracker-token-api.yaml index 15f3d631..3f919fbd 100644 --- a/docs/api/spec/treetracker-token-api.yaml +++ b/docs/api/spec/treetracker-token-api.yaml @@ -56,9 +56,9 @@ paths: type: integer format: int32 example: 10 - - name: start + - name: offset in: query - description: 'Where does the list start, 1 means start from the beginning of the list' + description: 'Where does the list offset, 0 means start from the beginning of the list' required: false style: form explode: true @@ -135,9 +135,9 @@ paths: type: integer format: int32 example: 10 - - name: start + - name: offset in: query - description: 'Where does the list start, 1 means start from the beginning of the list' + description: 'Where does the list offset, 0 means offset from the beginning of the list' required: false style: form explode: true @@ -256,9 +256,9 @@ paths: type: integer format: int32 example: 10 - - name: start + - name: offset in: query - description: 'Where does the list start, 1 means start from the beginning of the list' + description: 'Where does the list offset, 0 means offset from the beginning of the list' required: false style: form explode: true @@ -297,9 +297,9 @@ paths: type: integer format: int32 example: 10 - - name: start + - name: offset in: query - description: 'Where does the list start, 1 means start from the beginning of the list' + description: 'Where does the list offset, 0 means offset from the beginning of the list' required: false style: form explode: true @@ -453,9 +453,9 @@ paths: type: integer format: int32 example: 10 - - name: start + - name: offset in: query - description: 'Where does the list start, 1 means start from the beginning of the list' + description: 'Where does the list offset, 0 means offset from the beginning of the list' required: false style: form explode: true @@ -532,9 +532,9 @@ paths: type: integer format: int32 example: 10 - - name: start + - name: offset in: query - description: 'Where does the list start, 1 means start from the beginning of the list' + description: 'Where does the list offset, 0 means start from the beginning of the list' required: false style: form explode: true diff --git a/docs/api/treetracker-wallet-api-collection.json b/docs/api/treetracker-wallet-api-collection.json index a1653d53..9793583b 100644 --- a/docs/api/treetracker-wallet-api-collection.json +++ b/docs/api/treetracker-wallet-api-collection.json @@ -191,7 +191,7 @@ } ], "url": { - "raw": "{{BASE_URL}}/tokens/:token_uuid/transactions?limit=&start=", + "raw": "{{BASE_URL}}/tokens/:token_uuid/transactions?limit=&offset=", "host": [ "{{BASE_URL}}" ], @@ -207,7 +207,7 @@ "description": "(Required) " }, { - "key": "start", + "key": "offset", "value": "", "description": "(Required) " } @@ -248,7 +248,7 @@ } ], "url": { - "raw": "{{baseUrl}}/tokens/:token_uuid/transactions?limit=10&start=10", + "raw": "{{baseUrl}}/tokens/:token_uuid/transactions?limit=10&offset=10", "host": [ "{{baseUrl}}" ], @@ -263,7 +263,7 @@ "value": "10" }, { - "key": "start", + "key": "offset", "value": "10" } ], diff --git a/package-lock.json b/package-lock.json index fac96b36..91f0c0f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "treetracker", - "version": "1.11.1", + "version": "1.12.5", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -905,14 +905,108 @@ "dev": true }, "array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", "is-string": "^1.0.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "object-inspect": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + } } }, "array-slice": { @@ -926,13 +1020,106 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "array.prototype.flat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", - "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "object-inspect": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + } } }, "arrify": { @@ -1225,6 +1412,42 @@ } } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + }, + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + } + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1485,12 +1708,6 @@ "dot-prop": "^5.1.0" } }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", - "dev": true - }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -2417,6 +2634,12 @@ "prettier-linter-helpers": "^1.0.0" } }, + "eslint-plugin-simple-import-sort": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz", + "integrity": "sha512-U3vEDB5zhYPNfxT5TYR7u01dboFZp+HNpnGhkDB2g/2E4wZ/g1Q9Ton8UwCLfRV9yAKyYqDh62oHOamvkFxsvw==", + "dev": true + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -2531,6 +2754,57 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + } + } + }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -2881,15 +3155,6 @@ "path-exists": "^4.0.0" } }, - "find-versions": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz", - "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==", - "dev": true, - "requires": { - "semver-regex": "^2.0.0" - } - }, "findup-sync": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", @@ -3045,6 +3310,17 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", @@ -3185,6 +3461,12 @@ "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -3276,33 +3558,77 @@ } }, "husky": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.5.tgz", - "integrity": "sha512-E5S/1HMoDDaqsH8kDF5zeKEQbYqe3wL9zJDyqyYqc8I4vHBtAoxkDBGXox0lZ9RI+k5GyB728vZdmnM4bYap+g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-3.1.0.tgz", + "integrity": "sha512-FJkPoHHB+6s4a+jwPqBudBDvYZsoQW5/HBuMSehC8qDiCe50kpcxeqFoDSlow+9I6wg47YxBoT3WxaURlrDIIQ==", "dev": true, "requires": { - "chalk": "^4.0.0", + "chalk": "^2.4.2", "ci-info": "^2.0.0", - "compare-versions": "^3.6.0", - "cosmiconfig": "^7.0.0", - "find-versions": "^3.2.0", + "cosmiconfig": "^5.2.1", + "execa": "^1.0.0", + "get-stdin": "^7.0.0", "opencollective-postinstall": "^2.0.2", "pkg-dir": "^4.2.0", "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" + "read-pkg": "^5.2.0", + "run-node": "^1.0.0", + "slash": "^3.0.0" }, "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -3313,6 +3639,22 @@ "path-exists": "^4.0.0" } }, + "get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "dev": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -3340,6 +3682,16 @@ "p-limit": "^2.2.0" } }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -3348,6 +3700,53 @@ "requires": { "find-up": "^4.0.0" } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + } + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true } } }, @@ -3476,6 +3875,12 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-bigint": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz", + "integrity": "sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==", + "dev": true + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -3484,6 +3889,15 @@ "binary-extensions": "^2.0.0" } }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -3544,6 +3958,12 @@ } } }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -3620,6 +4040,12 @@ } } }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", + "dev": true + }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", @@ -3661,6 +4087,12 @@ "is-unc-path": "^1.0.0" } }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, "is-string": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", @@ -3918,6 +4350,12 @@ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -4830,6 +5268,12 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "nise": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", @@ -4936,6 +5380,23 @@ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + }, + "dependencies": { + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + } + } + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -5058,15 +5519,107 @@ } }, "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", + "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", + "es-abstract": "^1.18.0-next.2", "has": "^1.0.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "object-inspect": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + } } }, "on-finished": { @@ -5115,6 +5668,12 @@ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, "p-limit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", @@ -5854,6 +6413,12 @@ "glob": "^7.1.3" } }, + "run-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", + "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", + "dev": true + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -5873,9 +6438,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", - "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "semver-compare": { @@ -5899,12 +6464,6 @@ } } }, - "semver-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", - "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", - "dev": true - }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -6445,6 +7004,12 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, "strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", @@ -6742,6 +7307,26 @@ "is-typedarray": "^1.0.0" } }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + } + } + }, "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -6972,18 +7557,25 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true - }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -7136,8 +7728,7 @@ }, "y18n": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "resolved": "", "dev": true }, "yallist": { diff --git a/package.json b/package.json index f5c15e13..7467c27a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "treetracker", - "version": "1.12.0", + "version": "1.12.5", "description": "https://documenter.getpostman.com/view/10112806/SWTD8H5x?version=latest", "private": true, "main": "server/server.js", @@ -66,9 +66,10 @@ "eslint-config-prettier": "^6.13.0", "eslint-plugin-import": "^2.22.1", "eslint-plugin-prettier": "^3.2.0", + "eslint-plugin-simple-import-sort": "^7.0.0", "expect-runtime": "^0.7.0", "generate-password": "^1.6.0", - "husky": "^4.3.5", + "husky": "^3.1.0", "mock-knex": "^0.4.9", "prettier": "^2.1.2", "sinon": "^9.0.3", diff --git a/scripts/create/clean-up-duplicates.js b/scripts/create/clean-up-duplicates.js index 325fb124..bd28f6d3 100644 --- a/scripts/create/clean-up-duplicates.js +++ b/scripts/create/clean-up-duplicates.js @@ -6,60 +6,50 @@ function getRandomArbitrary(min, max) { } (async () => { - - const Knex = require('knex') + const Knex = require('knex'); const { v4: uuidv4 } = require('uuid'); const Config = require('./config/config'); const knex = Knex({ client: 'pg', - connection: Config.connectionString[process.env.NODE_ENV] - }) - - const csvFile = './duplicate.uuid.csv' + connection: Config.connectionString[process.env.NODE_ENV], + }); + const csvFile = './duplicate.uuid.csv'; const trx = await knex.transaction(); try { - - const csvString = await fs.readFile(csvFile, 'utf-8'); const rows = await csv.parse(csvString); - for(row of rows){ - console.log(row) - + for (const row of rows) { + console.log(row); - const uuid = row[0] - console.log(uuid) + const uuid = row[0]; + console.log(uuid); - const captures = await trx('trees').select(['id']).where({ uuid: uuid, active: true}) - console.log(captures.length) - captures.shift() // skip the first one + const captures = await trx('trees') + .select(['id']) + .where({ uuid, active: true }); + console.log(captures.length); + captures.shift(); // skip the first one - for(capture of captures){ - csonole.log('set false'); - console.log(capture.id) - await trx('trees').where({ id: capture.id }).update({active: false}) + for (const capture of captures) { + console.log('set false'); + console.log(capture.id); + await trx('trees').where({ id: capture.id }).update({ active: false }); } - } - await trx.commit(); - //await trx.rollback(); - - knex.destroy() + // await trx.rollback(); + knex.destroy(); } catch (error) { - - console.log('error') - console.log(error) - await trx.rollback() - knex.destroy() - + console.log('error'); + console.log(error); + await trx.rollback(); + knex.destroy(); } - - -})().catch(e => console.error(e.stack)); +})().catch((e) => console.error(e.stack)); diff --git a/scripts/create/create-tokens-csv.js b/scripts/create/create-tokens-csv.js index 333a3adf..84f6b0a0 100644 --- a/scripts/create/create-tokens-csv.js +++ b/scripts/create/create-tokens-csv.js @@ -6,81 +6,78 @@ function getRandomArbitrary(min, max) { } (async () => { - - const Knex = require('knex') + const Knex = require('knex'); const { v4: uuidv4 } = require('uuid'); const Config = require('./config/config'); const knex = Knex({ client: 'pg', - connection: Config.connectionString[process.env.NODE_ENV] - }) - - const targetWallet = 'GreenstandEscrow' - const csvFile = './GS_Not_Owned_20210313.csv' - const dryRun = false + connection: Config.connectionString[process.env.NODE_ENV], + }); + const targetWallet = 'GreenstandEscrow'; + const csvFile = './GS_Not_Owned_20210313.csv'; + const dryRun = true; const trx = await knex.transaction(); try { - - const wallet = await trx('wallet.wallet').first('*').where({ name: targetWallet }) - console.log(wallet) + const wallet = await trx('wallet.wallet') + .first('*') + .where({ name: targetWallet }); + console.log(wallet); const csvString = await fs.readFile(csvFile, 'utf-8'); const rows = await csv.parse(csvString); - rows.shift() - - for(row of rows){ - - console.log(row[0]) - console.log(parseInt(row[0])) - - const captureId = parseInt(row[0]) - - const capture = await trx('trees').select(['uuid', 'token_id', 'active']).where({ id: captureId }).first() - console.log(capture) - if(capture.token_id){ - console.log('token already assigned') - continue + rows.shift(); + + for (const row of rows) { + console.log(row[0]); + console.log(parseInt(row[0])); + + const captureId = parseInt(row[0]); + + const capture = await trx('trees') + .select(['uuid', 'token_id', 'active']) + .where({ id: captureId }) + .first(); + console.log(capture); + if (capture.token_id) { + console.log('token already assigned'); + continue; } - if(capture.active === false){ - console.log('capture is not active') - continue + if (capture.active === false) { + console.log('capture is not active'); + continue; } - //console.log('capture ' + capture.uuid); - tokenData = { + // console.log('capture ' + capture.uuid); + const tokenData = { capture_id: capture.uuid, - wallet_id: wallet.id - } - const result = await trx('wallet.token').insert(tokenData).returning('id') - const tokenId = result[0] - console.log({ id: capture.uuid }) - console.log({ token_id: tokenId }) - await trx('trees').where({ id: captureId }).update({ token_id: tokenId }) + wallet_id: wallet.id, + }; + const result = await trx('wallet.token') + .insert(tokenData) + .returning('id'); + const tokenId = result[0]; + console.log({ id: capture.uuid }); + console.log({ token_id: tokenId }); + await trx('trees').where({ id: captureId }).update({ token_id: tokenId }); } - - if(dryRun == true){ + if (dryRun === true) { console.log('Dry run: rolling back'); await trx.rollback(); } else { - console.log('Committing changes!') - //await trx.commit(); + console.log('Committing changes!'); + // await trx.commit(); } - knex.destroy() - + knex.destroy(); } catch (error) { - - console.log(error) - await trx.rollback() - knex.destroy() - + console.log(error); + await trx.rollback(); + knex.destroy(); } - - -})().catch(e => console.error(e.stack)); +})().catch((e) => console.error(e.stack)); diff --git a/scripts/create/create-tokens-fcc.js b/scripts/create/create-tokens-fcc.js index e63b0e40..6228b919 100644 --- a/scripts/create/create-tokens-fcc.js +++ b/scripts/create/create-tokens-fcc.js @@ -1,64 +1,59 @@ -function getRandomArbitrary(min, max) { - return Math.random() * (max - min) + min; -} - (async () => { - - const Knex = require('knex') + const Knex = require('knex'); const { v4: uuidv4 } = require('uuid'); + // eslint-disable-next-line import/no-unresolved const Config = require('./config/config'); const knex = Knex({ client: 'pg', - connection: Config.connectionString[process.env.NODE_ENV] - }) - + connection: Config.connectionString[process.env.NODE_ENV], + }); const trx = await knex.transaction(); try { + const wallet = await trx('wallet.wallet').first('*').where({ name: 'FCC' }); + console.log(wallet); - const wallet = await trx('wallet.wallet').first('*').where({ name: 'FCC' }) - console.log(wallet) + let remaining = true; - let remaining = true + while (remaining) { + const rows = await trx('trees') + .select('*') + .whereRaw( + 'planter_id IN (select id from planter where organization_id IN ( select entity_id from getEntityRelationshipChildren(?) ) ) AND active = true AND approved = true AND token_id IS NULL limit 3000', + [178], + ); - while(remaining) { - - const rows = await trx('trees').select('*').whereRaw('planter_id IN (select id from planter where organization_id IN ( select entity_id from getEntityRelationshipChildren(?) ) ) AND active = true AND approved = true AND token_id IS NULL limit 3000', [178]) - - if(rows.length < 3000){ - remaining = false + if (rows.length < 3000) { + remaining = false; } - for(capture of rows){ - - //console.log('capture ' + capture.uuid); - tokenData = { + for (const capture of rows) { + // console.log('capture ' + capture.uuid); + const tokenData = { capture_id: capture.uuid, - wallet_id: wallet.id - } - const result = await trx('wallet.token').insert(tokenData).returning('id') - const tokenId = result[0] - console.log({ id: capture.id }) - console.log({ token_id: tokenId }) - await trx('trees').where({ id: capture.id }).update({ token_id: tokenId }) + wallet_id: wallet.id, + }; + const result = await trx('wallet.token') + .insert(tokenData) + .returning('id'); + const tokenId = result[0]; + console.log({ id: capture.id }); + console.log({ token_id: tokenId }); + await trx('trees') + .where({ id: capture.id }) + .update({ token_id: tokenId }); } - } await trx.commit(); - //await trx.rollback(); - - knex.destroy() + // await trx.rollback(); + knex.destroy(); } catch (error) { - - console.log(error) - await trx.rollback() - knex.destroy() - + console.log(error); + await trx.rollback(); + knex.destroy(); } - - -})().catch(e => console.error(e.stack)); +})().catch((e) => console.error(e.stack)); diff --git a/scripts/create/create-tokens-kijani.js b/scripts/create/create-tokens-kijani.js index 933b7d98..923e32c7 100644 --- a/scripts/create/create-tokens-kijani.js +++ b/scripts/create/create-tokens-kijani.js @@ -3,51 +3,54 @@ function getRandomArbitrary(min, max) { } (async () => { - - const Knex = require('knex') + const Knex = require('knex'); const { v4: uuidv4 } = require('uuid'); + // eslint-disable-next-line import/no-unresolved const Config = require('./config/config'); const knex = Knex({ client: 'pg', - connection: Config.connectionString[process.env.NODE_ENV] - }) - + connection: Config.connectionString[process.env.NODE_ENV], + }); const trx = await knex.transaction(); try { - - const wallet = await trx('wallet.wallet').first('*').where({ name: 'KijaniForestry' }) - console.log(wallet) - - const rows = await trx('trees').select('*').whereRaw('planter_id IN (select id from planter where organization_id = ?) AND active = true AND approved = true AND token_id IS NULL', [7]) - - for(capture of rows){ - - //console.log('capture ' + capture.uuid); - tokenData = { + const wallet = await trx('wallet.wallet') + .first('*') + .where({ name: 'KijaniForestry' }); + console.log(wallet); + + const rows = await trx('trees') + .select('*') + .whereRaw( + 'planter_id IN (select id from planter where organization_id = ?) AND active = true AND approved = true AND token_id IS NULL', + [7], + ); + + for (const capture of rows) { + // console.log('capture ' + capture.uuid); + const tokenData = { capture_id: capture.uuid, - wallet_id: wallet.id - } - const result = await trx('wallet.token').insert(tokenData).returning('id') - const tokenId = result[0] - console.log({ id: capture.id }) - console.log({ token_id: tokenId }) - await trx('trees').where({ id: capture.id }).update({ token_id: tokenId }) + wallet_id: wallet.id, + }; + const result = await trx('wallet.token') + .insert(tokenData) + .returning('id'); + const tokenId = result[0]; + console.log({ id: capture.id }); + console.log({ token_id: tokenId }); + await trx('trees') + .where({ id: capture.id }) + .update({ token_id: tokenId }); } await trx.commit(); - knex.destroy() - + knex.destroy(); } catch (error) { - - console.log(error) - await trx.rollback() - knex.destroy() - + console.log(error); + await trx.rollback(); + knex.destroy(); } - - -})().catch(e => console.error(e.stack)); +})().catch((e) => console.error(e.stack)); diff --git a/scripts/create/create-wallet.js b/scripts/create/create-wallet.js index 8ed1a8ec..772fa7d1 100644 --- a/scripts/create/create-wallet.js +++ b/scripts/create/create-wallet.js @@ -30,13 +30,13 @@ function getRandomArbitrary(min, max) { }); const sha512 = function(password, salt){ - var hash = Crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ + const hash = Crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ hash.update(password); - var value = hash.digest('hex'); + const value = hash.digest('hex'); return value; }; - const salt = Crypto.randomBytes(32).toString('base64') //create a secure salt + const salt = Crypto.randomBytes(32).toString('base64') // create a secure salt const passwordHash = sha512(password, salt) const apiKey = generator.generate({ @@ -64,7 +64,7 @@ function getRandomArbitrary(min, max) { const result = await trx('wallet.wallet').insert({ name: username, password: passwordHash, - salt: salt + salt }).returning('*') const wallet = result[0] console.log(wallet) @@ -73,9 +73,9 @@ function getRandomArbitrary(min, max) { knex.destroy() - console.log('wallet ' + username); - console.log('password ' + password); - console.log('api key ' + apiKey); + console.log(`wallet ${ username}`); + console.log(`password ${ password}`); + console.log(`api key ${ apiKey}`); } catch (error) { diff --git a/scripts/demo/create-demo-wallet-simple.js b/scripts/demo/create-demo-wallet-simple.js index 145f1f7e..6fe63dc1 100644 --- a/scripts/demo/create-demo-wallet-simple.js +++ b/scripts/demo/create-demo-wallet-simple.js @@ -18,9 +18,9 @@ function getRandomArbitrary(min, max) { const Crypto = require('crypto'); const sha512 = function(password, salt){ - let hash = Crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ + const hash = Crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ hash.update(password); - let value = hash.digest('hex'); + const value = hash.digest('hex'); return value; }; diff --git a/scripts/demo/create-demo-wallet.js b/scripts/demo/create-demo-wallet.js index e849532c..61ae1462 100644 --- a/scripts/demo/create-demo-wallet.js +++ b/scripts/demo/create-demo-wallet.js @@ -1,71 +1,73 @@ - function getRandomArbitrary(min, max) { return Math.random() * (max - min) + min; } (async () => { - - const Knex = require('knex') + const Knex = require('knex'); const faker = require('faker'); const { v4: uuidv4 } = require('uuid'); - const Config = require('./config/config'); const knex = Knex({ client: 'pg', - connection: Config.connectionString[process.env.NODE_ENV] - }) + connection: Config.connectionString[process.env.NODE_ENV], + }); const Crypto = require('crypto'); - const sha512 = function(password, salt){ - var hash = Crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ + const sha512 = function (password, salt) { + const hash = Crypto.createHmac( + 'sha512', + salt, + ); /** Hashing algorithm sha512 */ hash.update(password); - var value = hash.digest('hex'); - return value; + return hash.digest('hex'); }; - const username = faker.internet.userName() - const password = faker.internet.password() // not a secure password - const apiKey = faker.internet.password() + const username = faker.internet.userName(); + const password = faker.internet.password(); // not a secure password + const apiKey = faker.internet.password(); - const salt = faker.internet.password() // not a secure salt - const passwordHash = sha512(password, salt) + const salt = faker.internet.password(); // not a secure salt + const passwordHash = sha512(password, salt); const trx = await knex.transaction(); try { - - // create API key const apiKeyData = { key: apiKey, tree_token_api_access: true, - name: username - } - const result0 = await trx('wallet.api_key').insert(apiKeyData).returning('*') - console.log(result0) + name: username, + }; + const result0 = await trx('wallet.api_key') + .insert(apiKeyData) + .returning('*'); + console.log(result0); // create wallet and password, salt - const result = await trx('wallet.wallet').insert({ - name: username, - password: passwordHash, - salt: salt - }).returning('*') - const wallet = result[0] - console.log(wallet) - + const result = await trx('wallet.wallet') + .insert({ + name: username, + password: passwordHash, + salt, + }) + .returning('*'); + const wallet = result[0]; + console.log(wallet); // insert fake planters const planterData = { first_name: faker.name.firstName(), last_name: faker.name.lastName(), email: faker.internet.email(), - phone: faker.phone.phoneNumber() - } - const result2 = await trx('public.planter').insert(planterData).returning('*') - const planter = result2[0] - console.log(planter) + phone: faker.phone.phoneNumber(), + }; + const result2 = await trx('public.planter') + .insert(planterData) + .returning('*'); + const planter = result2[0]; + console.log(planter); const images = [ 'https://treetracker-dev.nyc3.digitaloceanspaces.com/2018.06.14.19.59.24_ddb1452b-fec8-42df-aa67-5bf0b1337ffc_IMG_20180614_142511_234466904.jpg', @@ -76,55 +78,64 @@ function getRandomArbitrary(min, max) { 'https://treetracker-dev.nyc3.digitaloceanspaces.com/2018.06.14.19.59.40_14a8d4db-c1dd-449b-8534-a6b28a906e11_IMG_20180614_142737_-662610853.jpg', 'https://treetracker-dev.nyc3.digitaloceanspaces.com/2018.07.23.16.01.35_6319320a-4082-4db8-b2aa-38f9ade86566_IMG_20180723_131343_-895124767.jpg', 'https://treetracker-dev.nyc3.digitaloceanspaces.com/2018.07.23.16.30.00_229f166d-91f4-43fa-9332-f27a1d001473_IMG_20180723_135005_1449884218.jpg', - 'https://treetracker-dev.nyc3.digitaloceanspaces.com/2018.06.19.18.20.59_5559d3ad-9090-4456-a81e-00a7653483c0_IMG_20180619_142743_1430885612.jpg' - ] + 'https://treetracker-dev.nyc3.digitaloceanspaces.com/2018.06.19.18.20.59_5559d3ad-9090-4456-a81e-00a7653483c0_IMG_20180619_142743_1430885612.jpg', + ]; + + const planterImages = [ + 'https://treetracker-production-images.s3.eu-central-1.amazonaws.com/2020.11.19.15.23.46_8.42080836_-13.17032878_3c58d106-1893-493c-986b-061f66009b5a_IMG_20201118_110629_7276172223528929867.jpg', + 'https://treetracker-production-images.s3.eu-central-1.amazonaws.com/2020.11.17.12.45.48_8.42419553_-13.16719857_11d157fb-1bb0-4497-a7d7-7c16ce658158_IMG_20201117_104118_1916638584657622896.jpg', + ]; // insert fake tree captures - let trees = [] - for(i=0; i<5000; i++){ + const trees = []; + for (let i = 0; i < 1000; i++) { const captureData = { time_created: new Date(), time_updated: new Date(), planter_id: planter.id, - lat: getRandomArbitrary(-15,0), - lon: getRandomArbitrary(15,35), - image_url: images[Math.floor(getRandomArbitrary(1,9.99))], + lat: getRandomArbitrary(-15, 0), + lon: getRandomArbitrary(15, 35), + image_url: images[Math.floor(getRandomArbitrary(1, 9.99))], + planter_photo_url: + planterImages[Math.floor(getRandomArbitrary(1, 1.99))], uuid: uuidv4(), approved: true, - } - const result3 = await trx('public.trees').insert(captureData).returning('*') - const capture = result3[0] - trees.push(capture.uuid) - console.log(capture.uuid) - await trx.raw('UPDATE trees SET estimated_geometric_location = ST_SetSRID(ST_MakePoint(lon, lat), 4326) WHERE id = ?', capture.id) + }; + const result3 = await trx('public.trees') + .insert(captureData) + .returning('*'); + const capture = result3[0]; + trees.push(capture.uuid); + console.log(capture.uuid); + await trx.raw( + 'UPDATE trees SET estimated_geometric_location = ST_SetSRID(ST_MakePoint(lon, lat), 4326) WHERE id = ?', + capture.id, + ); } // create fake tokens - for ( const treeId of trees ){ + for (const treeId of trees) { const tokenData = { capture_id: treeId, - wallet_id: wallet.id - } - const result4 = await trx('wallet.token').insert(tokenData).returning('*') - const token = result4[0] - console.log(token.id) + wallet_id: wallet.id, + }; + const result4 = await trx('wallet.token') + .insert(tokenData) + .returning('*'); + const token = result4[0]; + console.log(token.id); } await trx.commit(); - knex.destroy() - - console.log('wallet ' + username); - console.log('password ' + password); - console.log('apiKey ' + apiKey); + knex.destroy(); + console.log(`wallet ${username}`); + console.log(`password ${password}`); + console.log(`apiKey ${apiKey}`); } catch (error) { - - console.log(error) - await trx.rollback() - knex.destroy() - + console.log(error); + await trx.rollback(); + knex.destroy(); } - - -})().catch(e => console.error(e.stack)); +})().catch((e) => console.error(e.stack)); diff --git a/scripts/user/sha.js b/scripts/user/sha.js index 632c4fb4..83ea7a70 100644 --- a/scripts/user/sha.js +++ b/scripts/user/sha.js @@ -1,15 +1,16 @@ const Crypto = require('crypto'); + const sha512 = function(password, salt){ - var hash = Crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ + const hash = Crypto.createHmac('sha512', salt); /** Hashing algorithm sha512 */ hash.update(password); - var value = hash.digest('hex'); + const value = hash.digest('hex'); return value; }; const key = 'MyGreat38473'; const salt = 'j5qI1qb2rsgVBJvjiXx1isnR4bQW6Yd3'; const hash = sha512(key, salt); -console.log("key: " + key); -console.log("salt: " + salt); -console.log("hash: " + hash); +console.log(`key: ${ key}`); +console.log(`salt: ${ salt}`); +console.log(`hash: ${ hash}`); diff --git a/server/app.js b/server/app.js index 47c355b8..ec9263b9 100644 --- a/server/app.js +++ b/server/app.js @@ -4,6 +4,7 @@ const bodyParser = require('body-parser'); const asyncHandler = require('express-async-handler'); const { check, validationResult } = require('express-validator'); const { body } = require('express-validator'); +const log = require("loglevel"); const HttpError = require("./utils/HttpError"); const authRouter = require('./routes/authRouter.js') const trustRouter = require('./routes/trustRouter.js') @@ -11,7 +12,6 @@ const tokenRouter = require('./routes/tokenRouter.js') const transferRouter = require("./routes/transferRouter"); const walletRouter = require("./routes/walletRouter"); const {errorHandler} = require("./routes/utils"); -const log = require("loglevel"); const helper = require("./routes/utils"); @@ -36,7 +36,7 @@ app.use(helper.handlerWrapper(async (req, _res, next) => { app.use(bodyParser.urlencoded({ extended: false })); // parse application/x-www-form-urlencoded app.use(bodyParser.json()); // parse application/json -//routers +// routers app.use('/auth', authRouter); app.use('/tokens', tokenRouter); app.use('/trust_relationships', trustRouter); @@ -53,8 +53,8 @@ app.get('/wallet/:wallet_id/event', asyncHandler(async (req, res, next) => { app.post('/wallet/:wallet_id/trust/request', asyncHandler(async (req, res, next) => { - const type = req.body.type; - //const requestor_wallet_id = req.body.wallet_id; this is in the bearer token + const {type} = req.body; + // const requestor_wallet_id = req.body.wallet_id; this is in the bearer token const requested_wallet_id = req.params.wallet_id; @@ -62,8 +62,8 @@ app.post('/wallet/:wallet_id/trust/request', asyncHandler(async (req, res, next) app.post('/wallet/:wallet_id/trust/approve', asyncHandler(async (req, res, next) => { - const type = req.body.type; - //const wallet_id = req.body.wallet_id; // in the bearer token + const {type} = req.body; + // const wallet_id = req.body.wallet_id; // in the bearer token const approved_wallet_id = req.params.wallet_id; })); @@ -71,7 +71,8 @@ app.post('/wallet/:wallet_id/trust/approve', asyncHandler(async (req, res, next) // Global error handler app.use(errorHandler); -const version = require('../package.json').version +const {version} = require('../package.json') + app.get('*',function (req, res) { res.status(200).send(version) }); diff --git a/server/app.spec.js b/server/app.spec.js index ca987544..e06248aa 100644 --- a/server/app.spec.js +++ b/server/app.spec.js @@ -1,6 +1,6 @@ -const server = require("../server/app"); const request = require('supertest'); const { expect } = require('chai'); +const server = require("./app"); describe("", () => { diff --git a/server/database/knex.js b/server/database/knex.js index 956d6da7..b75167a3 100644 --- a/server/database/knex.js +++ b/server/database/knex.js @@ -1,17 +1,18 @@ require('dotenv').config() const expect = require('expect-runtime'); const connection = require('../../config/config').connectionString; + expect(connection).to.match(/^postgresql:\//); const log = require("loglevel"); -let knexConfig = { +const knexConfig = { client: 'pg', - debug: process.env.NODE_LOG_LEVEL === "debug"? true:false, + debug: process.env.NODE_LOG_LEVEL === "debug", connection, pool: { min:0, max: 100, - afterCreate: function (conn, done) { + afterCreate (conn, done) { conn.query('SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;', function (err) { if (err) { log.error(err) diff --git a/server/models/Session.js b/server/models/Session.js index f8c9ebb2..5f77bc2e 100644 --- a/server/models/Session.js +++ b/server/models/Session.js @@ -11,9 +11,9 @@ class Session{ getDB(){ if(this.thx){ return this.thx; - }else{ - return knex; } + return knex; + } async beginTransaction(){ diff --git a/server/models/Session.spec.js b/server/models/Session.spec.js index fb082dfc..35479c10 100644 --- a/server/models/Session.spec.js +++ b/server/models/Session.spec.js @@ -1,8 +1,9 @@ -const Session = require("./Session"); const jestExpect = require("expect"); const sinon = require("sinon"); const chai = require("chai"); const sinonChai = require("sinon-chai"); +const Session = require("./Session"); + chai.use(sinonChai); const {expect} = chai; diff --git a/server/models/Token.js b/server/models/Token.js index 5e9c7807..67040b39 100644 --- a/server/models/Token.js +++ b/server/models/Token.js @@ -1,20 +1,19 @@ -const log = require("loglevel"); -const TokenRepository = require("../repositories/TokenRepository"); -const TransactionRepository = require("../repositories/TransactionRepository"); -const HttpError = require("../utils/HttpError"); +const log = require('loglevel'); const { validate: uuidValidate } = require('uuid'); -const Joi = require("joi"); -const expect = require("expect-runtime"); - -class Token{ - - constructor(idOrJSON, session){ - if(uuidValidate(idOrJSON)){ +const Joi = require('joi'); +const expect = require('expect-runtime'); +const TokenRepository = require('../repositories/TokenRepository'); +const TransactionRepository = require('../repositories/TransactionRepository'); +const HttpError = require('../utils/HttpError'); + +class Token { + constructor(idOrJSON, session) { + if (uuidValidate(idOrJSON)) { this._id = idOrJSON; - }else if(typeof idOrJSON === "object" && uuidValidate(idOrJSON.id) ){ + } else if (typeof idOrJSON === 'object' && uuidValidate(idOrJSON.id)) { this._id = idOrJSON.id; this._JSON = idOrJSON; - }else{ + } else { throw new HttpError(500, `wrong contructor:${idOrJSON}`); } this.tokenRepository = new TokenRepository(session); @@ -22,26 +21,25 @@ class Token{ this._session = session; } - getId(){ + getId() { return this._id; } - async toJSON(){ - if(this._JSON){ - }else{ + async toJSON() { + if (!this._JSON) { this._JSON = await this.tokenRepository.getById(this._id); } - //deal with tree links + // deal with tree links const result = { ...this._JSON, links: { - capture: `/webmap/tree?uuid=${this._JSON.capture_id}` - } - } + capture: `/webmap/tree?uuid=${this._JSON.capture_id}`, + }, + }; return result; } - clearJSON(){ + clearJSON() { this._JSON = undefined; } @@ -57,7 +55,6 @@ class Token{ transfer_pending_id: null, wallet_id: transfer.destination_wallet_id, }); - await this.tokenRepository.update({ id: this._id, transfer_pending: false, @@ -78,12 +75,8 @@ class Token{ /* * To pending this token on the given transfer */ - async pendingTransfer(transfer){ - - Joi.assert( - transfer.id, - Joi.string().guid() - ) + async pendingTransfer(transfer) { + Joi.assert(transfer.id, Joi.string().guid()); await this.tokenRepository.update({ id: this._id, @@ -92,46 +85,42 @@ class Token{ }); } - async cancelTransfer(transfer){ - log.debug("Token cancel transfer"); + async cancelTransfer(transfer) { + log.debug('Token cancel transfer'); await this.tokenRepository.update({ id: this._id, transfer_pending: false, - transfer_pending_id: null + transfer_pending_id: null, }); } - async belongsTo(wallet){ - - Joi.assert( - wallet.getId(), - Joi.string().guid() - ) + async belongsTo(wallet) { + Joi.assert(wallet.getId(), Joi.string().guid()); const json = await this.toJSON(); - if(json.wallet_id === wallet.getId()){ + if (json.wallet_id === wallet.getId()) { return true; - }else{ - return false; } + return false; } - async beAbleToTransfer(){ + async beAbleToTransfer() { const json = await this.toJSON(); - if(json.transfer_pending === false){ + if (json.transfer_pending === false) { return true; - }else{ - return false; } + return false; } - async getTransactions(){ - const transactions = await this.transactionRepository.getByFilter({ - token_id: this._id, - }); + async getTransactions(limit, offset = 0) { + const transactions = await this.transactionRepository.getByFilter( + { + token_id: this._id, + }, + { limit, offset }, + ); return transactions; } - } module.exports = Token; diff --git a/server/models/Token.spec.js b/server/models/Token.spec.js index bdcea967..a2461dfa 100644 --- a/server/models/Token.spec.js +++ b/server/models/Token.spec.js @@ -1,19 +1,20 @@ -const Token = require("./Token"); const jestExpect = require("expect"); const sinon = require("sinon"); -const TokenRepository = require("../repositories/TokenRepository"); -const HttpError = require("../utils/HttpError"); const chai = require("chai"); const sinonChai = require("sinon-chai"); +const uuid = require('uuid'); +const Token = require("./Token"); +const TokenRepository = require("../repositories/TokenRepository"); +const HttpError = require("../utils/HttpError"); + chai.use(sinonChai); const {expect} = chai; const TransactionRepository = require("../repositories/TransactionRepository"); const Wallet = require("./Wallet"); const Session = require("./Session"); -const uuid = require('uuid'); describe("Token", () => { - let session = new Session(); + const session = new Session(); const tokenId = uuid.v4() const transferId = uuid.v4() diff --git a/server/models/TrustRelationship.js b/server/models/TrustRelationship.js index f2ab78f2..4f0b462d 100644 --- a/server/models/TrustRelationship.js +++ b/server/models/TrustRelationship.js @@ -1,6 +1,6 @@ const HttpError = require("../utils/HttpError"); -//NOTE: currently, don't have model for trust, here just defined some fields -//for this model +// NOTE: currently, don't have model for trust, here just defined some fields +// for this model const TrustRelationship = {} TrustRelationship.ENTITY_TRUST_TYPE = { diff --git a/server/models/TrustRelationship.spec.js b/server/models/TrustRelationship.spec.js index f4297f3a..2957e2fe 100644 --- a/server/models/TrustRelationship.spec.js +++ b/server/models/TrustRelationship.spec.js @@ -2,6 +2,7 @@ const jestExpect = require("expect"); const sinon = require("sinon"); const chai = require("chai"); const sinonChai = require("sinon-chai"); + chai.use(sinonChai); const {expect} = chai; const TrustRelationship = require("./TrustRelationship"); diff --git a/server/models/Wallet.js b/server/models/Wallet.js index f7d2684d..96ac5d52 100644 --- a/server/models/Wallet.js +++ b/server/models/Wallet.js @@ -1,15 +1,15 @@ +const Crypto = require('crypto'); +const log = require("loglevel"); +const { validate: uuidValidate } = require('uuid'); +const expect = require("expect-runtime"); // TODO: We should use Joi for validation +const Joi = require("joi"); const WalletRepository = require("../repositories/WalletRepository"); const TrustRepository = require("../repositories/TrustRepository"); -const TrustRelationship = require("../models/TrustRelationship"); +const TrustRelationship = require("./TrustRelationship"); const TransferRepository = require("../repositories/TransferRepository"); const HttpError = require("../utils/HttpError"); -const Crypto = require('crypto'); -const log = require("loglevel"); const Transfer = require("./Transfer"); const Token = require("./Token"); -const { validate: uuidValidate } = require('uuid'); -const expect = require("expect-runtime"); //TODO: We should use Joi for validation -const Joi = require("joi"); class Wallet{ @@ -42,7 +42,7 @@ class Wallet{ throw new HttpError(400, 'No password supplied'); } - let walletObject = await this.toJSON(); + const walletObject = await this.toJSON(); const hash = Wallet.sha512(password, walletObject.salt); if (hash !== walletObject.password) { @@ -58,13 +58,13 @@ class Wallet{ throw new HttpError(400, 'No wallet supplied'); } - //check name + // check name try{ await this.walletRepository.getByName(wallet); throw new HttpError(403, `The wallet '${wallet}' has been existed`); }catch(e){ if(e instanceof HttpError && e.code === 404){ - //fine + // fine }else{ throw e; } @@ -101,7 +101,7 @@ class Wallet{ /* * Get trust relationships by filters, setting filter to undefined to allow all data */ - async getTrustRelationships(state, type, request_type){ + async getTrustRelationships(state, type, request_type, offset, limit){ const filter = { and: [], } @@ -123,7 +123,7 @@ class Wallet{ originator_wallet_id: this._id, }] }); - return await this.trustRepository.getByFilter(filter); + return await this.trustRepository.getByFilter(filter, {offset, limit}); } /* @@ -173,10 +173,10 @@ class Wallet{ async toJSON(){ if(this._JSON){ return this._JSON; - }else{ + } this._JSON = await this.walletRepository.getById(this._id); return this._JSON; - } + } /* @@ -196,8 +196,8 @@ class Wallet{ /* * Translate the requester/ee to actor/target */ - let actorWallet = requesterWallet; //case of: manage/send - let targetWallet = requesteeWallet; //case of: mange/send + const actorWallet = requesterWallet; // case of: manage/send + const targetWallet = requesteeWallet; // case of: mange/send // if( // requestType === TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.receive || // requestType === TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.yield){ @@ -207,16 +207,16 @@ class Wallet{ - //check if the orginator can control the actor + // check if the orginator can control the actor const hasControl = await this.hasControlOver(requesterWallet); if(!hasControl){ throw new HttpError(403, "Have no permission to deal with this actor"); } - //check if the target wallet can accept the request + // check if the target wallet can accept the request await requesteeWallet.checkTrustRequestSentToMe(requestType, this.id); - //create this request + // create this request const trustRelationship = { type: TrustRelationship.getTrustTypeByRequestType(requestType), request_type: requestType, @@ -230,7 +230,7 @@ class Wallet{ return result; } - //check if I (current wallet) can add a new trust like this + // check if I (current wallet) can add a new trust like this async checkDuplicateRequest(trustRelationship){ const trustRelationships = await this.getTrustRelationships(); if( @@ -259,9 +259,9 @@ class Wallet{ ) ){ return true; - }else{ - return false; } + return false; + }) ){ log.debug("Has duplicated trust"); @@ -281,7 +281,7 @@ class Wallet{ * sourceWalletId: the wallet id related to the trust relationship with me, */ async checkTrustRequestSentToMe(requestType, sourceWalletId){ - //pass + // pass } /* @@ -292,9 +292,9 @@ class Wallet{ const trustRelationship = trustRelationships.reduce((a,c) => { if(c.id === trustRelationshipId){ return c; - }else{ - return a; } + return a; + }, undefined); if(!trustRelationship){ throw new HttpError(403, "Have no permission to accept this relationship"); @@ -307,9 +307,9 @@ class Wallet{ async checkManageCircle(trustRelationship){ const trustRelationshipTrusted = await this.getTrustRelationshipsTrusted(); - //just manage type of trust relationship + // just manage type of trust relationship if(trustRelationship.type === TrustRelationship.ENTITY_TRUST_TYPE.manage){ - //if is mange request + // if is mange request if(trustRelationship.request_type === TrustRelationship.ENTITY_TRUST_TYPE.manage){ if(trustRelationshipTrusted.some(e => { if( @@ -326,9 +326,9 @@ class Wallet{ ) ){ return true; - }else{ - return false; } + return false; + })){ throw new HttpError(403, "Operation forbidden, because this would lead to a management circle"); } @@ -348,9 +348,9 @@ class Wallet{ ) ){ return true; - }else{ - return false; } + return false; + })){ throw new HttpError(403, "Operation forbidden, because this would lead to a management circle"); } @@ -366,9 +366,9 @@ class Wallet{ const trustRelationship = trustRelationships.reduce((a,c) => { if(c.id === trustRelationshipId){ return c; - }else{ - return a; } + return a; + }, undefined); if(!trustRelationship){ throw new HttpError(403, "Have no permission to decline this relationship"); @@ -400,7 +400,7 @@ class Wallet{ expect(senderWallet).instanceOf(Wallet); expect(receiveWallet).instanceOf(Wallet); const trustRelationships = await this.getTrustRelationshipsTrusted(); - //check if the trust exist + // check if the trust exist if( trustRelationships.some(trustRelationship => { /* Seems unnecessary @@ -417,9 +417,9 @@ class Wallet{ trustRelationship.request_type === TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send ){ return true; - }else{ - return false; } + return false; + }) || trustRelationships.some(trustRelationship => { @@ -437,16 +437,16 @@ class Wallet{ trustRelationship.request_type === TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.receive ){ return true; - }else{ - return false; } + return false; + }) ){ log.debug("check trust passed"); return true; - }else{ - return false; } + return false; + } /* @@ -454,7 +454,7 @@ class Wallet{ */ async transfer(sender, receiver, tokens, claimBoolean){ // await this.checkDeduct(sender, receiver); - //check tokens belong to sender + // check tokens belong to sender for(const token of tokens){ if(!await token.belongsTo(sender)){ const uuid = await token.getId(); @@ -469,7 +469,7 @@ class Wallet{ const hasTrust = await this.hasTrust(TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, sender, receiver); const hasControlOverSender = await this.hasControlOver(sender); const hasControlOverReceiver = await this.hasControlOver(receiver); - //If has the trust, and is not deduct request (now, if wallet request some token from another wallet, can not pass the transfer directly) + // If has the trust, and is not deduct request (now, if wallet request some token from another wallet, can not pass the transfer directly) if( (hasControlOverSender && hasControlOverReceiver) || (!isDeduct && hasTrust) @@ -499,11 +499,18 @@ class Wallet{ log.debug("now, deal with tokens"); await this.tokenService.completeTransfer(tokens, transfer, claimBoolean); return transfer; - }else{ + + + // TODO: Do I need claim boolean in below cases? + } + // else{ + + // } + if(hasControlOverSender){ log.debug("OK, no permission, source under control, now pending it"); const tokensId = []; - for(let token of tokens){ + for(const token of tokens){ tokensId.push(token.getId()); } const transfer = await this.transferRepository.create({ @@ -527,10 +534,10 @@ class Wallet{ } } return transfer; - }else if(hasControlOverReceiver){ + }if(hasControlOverReceiver){ log.debug("OK, no permission, receiver under control, now request it"); const tokensId = []; - for(let token of tokens){ + for(const token of tokens){ tokensId.push(token.getId()); } const transfer = await this.transferRepository.create({ @@ -554,20 +561,21 @@ class Wallet{ } } return transfer; - }else{ + } // TODO expect.fail(); - } - } + + } + async transferBundle(sender, receiver, bundleSize, claimBoolean){ - //check has enough tokens to sender + // check has enough tokens to sender const tokenCount = await this.tokenService.countTokenByWallet(sender); // count number of tokens not claimed const notClaimedTokenCount = await this.tokenService.countNotClaimedTokenByWallet(sender); // if(tokenCount < bundleSize){ - // throw new HttpError(403, `Do not have enough tokens to send`); + // throw new HttpError(403, `Do not have enough tokens to send`); // } // console.log(notClaimedTokenCount); if(notClaimedTokenCount < bundleSize){ @@ -575,7 +583,7 @@ class Wallet{ } const isDeduct = await this.isDeduct(sender,receiver); - //If has the trust, and is not deduct request (now, if wallet request some token from another wallet, can not pass the transfer directly) + // If has the trust, and is not deduct request (now, if wallet request some token from another wallet, can not pass the transfer directly) const hasTrust = await this.hasTrust(TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, sender, receiver); const hasControlOverSender = await this.hasControlOver(sender); const hasControlOverReceiver = await this.hasControlOver(receiver); @@ -590,10 +598,10 @@ class Wallet{ state: Transfer.STATE.completed, parameters: { bundle: { - bundleSize: bundleSize, + bundleSize, } }, - //TODO: boolean for claim + // TODO: boolean for claim claim: claimBoolean, }); log.debug("now, deal with tokens"); @@ -601,7 +609,7 @@ class Wallet{ // need to check if tokens are not claim await this.tokenService.completeTransfer(tokens, transfer, claimBoolean); return transfer; - }else{ + } if(hasControlOverSender){ log.debug("OK, no permission, source under control, now pending it"); const transfer = await this.transferRepository.create({ @@ -611,14 +619,14 @@ class Wallet{ state: Transfer.STATE.pending, parameters: { bundle: { - bundleSize: bundleSize, + bundleSize, } }, - //TODO: boolean for claim + // TODO: boolean for claim claim: claimBoolean, }); return transfer; - }else if(hasControlOverReceiver){ + }if(hasControlOverReceiver){ log.debug("OK, no permission, receiver under control, now request it"); const transfer = await this.transferRepository.create({ originator_wallet_id: this._id, @@ -627,29 +635,29 @@ class Wallet{ state: Transfer.STATE.requested, parameters: { bundle: { - bundleSize: bundleSize, + bundleSize, } }, claim: claimBoolean }); return transfer; - }else{ - //TODO - expect.fail(); } - } + // TODO + expect.fail(); + + } /* * I have control over given wallet */ async hasControlOver(wallet){ - //if the given wallet is me, then pass + // if the given wallet is me, then pass if(wallet.getId() === this._id){ log.debug("The same wallet, control"); return true; - }else{ - //check sub wallet + } + // check sub wallet const result = await this.trustRepository.getByFilter({ or: [ { @@ -678,10 +686,10 @@ class Wallet{ }); if(result.length > 0){ return true; - }else{ - return false; } - } + return false; + + } /* @@ -710,9 +718,9 @@ class Wallet{ transfer.state = Transfer.STATE.completed; const transferJson = await this.transferRepository.update(transfer); - //deal with tokens + // deal with tokens if( - //TODO optimize + // TODO optimize transfer.parameters && transfer.parameters.bundle && transfer.parameters.bundle.bundleSize){ @@ -759,7 +767,7 @@ class Wallet{ transfer.state = Transfer.STATE.cancelled; const transferJson = await this.transferRepository.update(transfer); - //deal with tokens + // deal with tokens const tokens = await this.tokenService.getTokensByPendingTransferId(transfer.id); await this.tokenService.cancelTransfer(tokens, transfer); return transferJson; @@ -786,7 +794,7 @@ class Wallet{ transfer.state = Transfer.STATE.cancelled; const transferJson = await this.transferRepository.update(transfer); - //deal with tokens + // deal with tokens const tokens = await this.tokenService.getTokensByPendingTransferId(transfer.id); await this.tokenService.cancelTransfer(tokens, transfer); return transferJson; @@ -796,7 +804,7 @@ class Wallet{ * Fulfill a requested transfer, if I has the privilege to do so */ async fulfillTransfer(transferId){ - //TODO check privilege + // TODO check privilege const transfer = await this.transferRepository.getById(transferId); const sender = await this.walletService.getById(transfer.source_wallet_id); @@ -810,9 +818,9 @@ class Wallet{ transfer.state = Transfer.STATE.completed; const transferJson = await this.transferRepository.update(transfer); - //deal with tokens + // deal with tokens if( - //TODO optimize + // TODO optimize transfer.parameters && transfer.parameters.bundle && transfer.parameters.bundle.bundleSize){ @@ -834,7 +842,7 @@ class Wallet{ * Specify tokens */ async fulfillTransferWithTokens(transferId, tokens){ - //TODO check privilege + // TODO check privilege const transfer = await this.transferRepository.getById(transferId); const sender = await this.walletService.getById(transfer.source_wallet_id); @@ -848,16 +856,16 @@ class Wallet{ transfer.state = Transfer.STATE.completed; const transferJson = await this.transferRepository.update(transfer); - //deal with tokens + // deal with tokens if( - //TODO optimize + // TODO optimize transfer.parameters && transfer.parameters.bundle && transfer.parameters.bundle.bundleSize){ log.debug("transfer bundle of tokens"); const {source_wallet_id} = transfer; const senderWallet = new Wallet(source_wallet_id, this._session); - //check it + // check it if(tokens.length > transfer.parameters.bundle.bundleSize){ throw new HttpError(403, `Too many tokens to transfer, please provider ${transfer.parameters.bundle.bundleSize} tokens for this transfer`, true); } @@ -872,7 +880,7 @@ class Wallet{ } } - //transfer + // transfer await this.tokenService.completeTransfer(tokens, transfer); }else{ throw new HttpError(403, "No need to specify tokens", true); @@ -883,7 +891,7 @@ class Wallet{ /* * Get all transfers belongs to me */ - async getTransfers(state, wallet){ + async getTransfers(state, wallet, offset = 0, limit){ const filter = { and: [], } @@ -910,8 +918,7 @@ class Wallet{ }] }); } - const result = await this.transferRepository.getByFilter(filter); - return result; + return await this.transferRepository.getByFilter(filter, {offset, limit} ); } async getTransferById(id){ @@ -919,9 +926,9 @@ class Wallet{ const transfer = transfers.reduce((a,c) => { if(c.id === id){ return c; - }else{ - return a; } + return a; + }, undefined); if(!transfer){ throw new HttpError(404, "Can not find this transfer or it is related to this wallet"); @@ -929,13 +936,13 @@ class Wallet{ return transfer; } - async getTokensByTransferId(id){ + async getTokensByTransferId(id, limit, offset){ const transfer = await this.getTransferById(id); let tokens; if(transfer.state === Transfer.STATE.completed){ - tokens = await this.tokenService.getTokensByTransferId(transfer.id); + tokens = await this.tokenService.getTokensByTransferId(transfer.id, limit, offset); }else{ - tokens = await this.tokenService.getTokensByPendingTransferId(transfer.id); + tokens = await this.tokenService.getTokensByPendingTransferId(transfer.id, limit, offset); } return tokens; } @@ -950,18 +957,18 @@ class Wallet{ const result = await this.hasControlOver(sender); if(result){ return false; - }else{ - return true; } + return true; + } /* * Get all wallet managed by me */ async getSubWallets(){ - let trustRelationships = await this.getTrustRelationships(); + const trustRelationships = await this.getTrustRelationships(); const subWallets = []; - for(let e of trustRelationships){ + for(const e of trustRelationships){ if( e.actor_wallet_id === this._id && e.request_type === TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.manage && diff --git a/server/models/Wallet.spec.js b/server/models/Wallet.spec.js index e5b27457..6ade5083 100644 --- a/server/models/Wallet.spec.js +++ b/server/models/Wallet.spec.js @@ -1,44 +1,48 @@ -const Wallet = require("./Wallet"); -const jestExpect = require("expect"); -const sinon = require("sinon"); -const chai = require("chai"); -const sinonChai = require("sinon-chai"); -chai.use(sinonChai); -const {expect} = chai; -const WalletRepository = require("../repositories/WalletRepository"); -const TrustRepository = require("../repositories/TrustRepository"); -const WalletService = require("../services/WalletService"); -const TransferRepository = require("../repositories/TransferRepository"); -const HttpError = require("../utils/HttpError"); -const TrustRelationship = require("../models/TrustRelationship"); -const Transfer = require("./Transfer"); -const Token = require("./Token"); -const TokenService = require("../services/TokenService"); -const Session = require("./Session"); +const jestExpect = require('expect'); +const sinon = require('sinon'); +const chai = require('chai'); +const sinonChai = require('sinon-chai'); const uuid = require('uuid'); +const Wallet = require('./Wallet'); -describe("Wallet", () => { +chai.use(sinonChai); +const { expect } = chai; +const WalletRepository = require('../repositories/WalletRepository'); +const TrustRepository = require('../repositories/TrustRepository'); +const WalletService = require('../services/WalletService'); +const TransferRepository = require('../repositories/TransferRepository'); +const HttpError = require('../utils/HttpError'); +const TrustRelationship = require('./TrustRelationship'); +const Transfer = require('./Transfer'); +const Token = require('./Token'); +const TokenService = require('../services/TokenService'); +const Session = require('./Session'); + +describe('Wallet', () => { let walletService; - let session = new Session(); + let wallet; + const session = new Session(); const walletObject = { - id: uuid.v4(), - salt:"salet", - password: "testPasswordHash", + id: uuid.v4(), + salt: 'salet', + password: 'testPasswordHash', }; beforeEach(() => { wallet = new Wallet(uuid.v4(), session); walletService = new WalletService(session); - }) + }); afterEach(() => { sinon.restore(); }); - it("authorize() with empty parameters should get 400 error", async () => { - sinon.stub(WalletRepository.prototype, "getByName").resolves({id:uuid.v4()}); - const wallet = await walletService.getByName("test"); + it('authorize() with empty parameters should get 400 error', async () => { + sinon + .stub(WalletRepository.prototype, 'getByName') + .resolves({ id: uuid.v4() }); + const wallet = await walletService.getByName('test'); expect(wallet).instanceOf(Wallet); await jestExpect(async () => { await wallet.authorize(undefined); @@ -47,51 +51,52 @@ describe("Wallet", () => { }); it("authorize() with wallet which doesn't exists, should throw 401", async () => { - sinon.stub(WalletRepository.prototype, "getByName").rejects(new HttpError(404, "not found")); + sinon + .stub(WalletRepository.prototype, 'getByName') + .rejects(new HttpError(404, 'not found')); await jestExpect(async () => { - const wallet = await walletService.getByName("test"); + const wallet = await walletService.getByName('test'); await wallet.authorize(undefined); }).rejects.toThrow(/not found/); WalletRepository.prototype.getByName.restore(); }); - - it("authorize() with correct wallet, password, should return a wallet object", async () => { - sinon.stub(WalletRepository.prototype, "getById").resolves(walletObject); - sinon.stub(Wallet, "sha512").returns("testPasswordHash"); - const walletObjectResult = await wallet.authorize("testPassword"); - expect(walletObjectResult).property("id").eq(walletObject.id); + it('authorize() with correct wallet, password, should return a wallet object', async () => { + sinon.stub(WalletRepository.prototype, 'getById').resolves(walletObject); + sinon.stub(Wallet, 'sha512').returns('testPasswordHash'); + const walletObjectResult = await wallet.authorize('testPassword'); + expect(walletObjectResult).property('id').eq(walletObject.id); WalletRepository.prototype.getById.restore(); Wallet.sha512.restore(); }); - - it("getTrustRelationshipsRequested", async () => { - const fn = sinon.stub(Wallet.prototype, "getTrustRelationships").resolves([{ - id: uuid.v4(), - originator_wallet_id: wallet.getId(), - }]); + it('getTrustRelationshipsRequested', async () => { + const fn = sinon.stub(Wallet.prototype, 'getTrustRelationships').resolves([ + { + id: uuid.v4(), + originator_wallet_id: wallet.getId(), + }, + ]); const trust_relationships = await wallet.getTrustRelationshipsRequested(); expect(trust_relationships).lengthOf(1); fn.restore(); }); - describe("Request trust", () => { - - const wallet = new Wallet(uuid.v4()) - const wallet2 = new Wallet(uuid.v4()) - const wallet3 = new Wallet(uuid.v4()) + describe('Request trust', () => { + const wallet = new Wallet(uuid.v4()); + const wallet2 = new Wallet(uuid.v4()); + const wallet3 = new Wallet(uuid.v4()); - it("request with a wrong type would throw error", async () => { + it('request with a wrong type would throw error', async () => { await jestExpect(async () => { - await wallet.requestTrustFromAWallet("wrongType","test") - }).rejects.toThrow("must be one of"); + await wallet.requestTrustFromAWallet('wrongType', 'test'); + }).rejects.toThrow('must be one of'); }); - it("request successfully", async () => { - const fn2 = sinon.stub(TrustRepository.prototype, "get").resolves([]); - const fn3 = sinon.stub(TrustRepository.prototype, "create"); - sinon.stub(Wallet.prototype, "checkDuplicateRequest"); + it('request successfully', async () => { + const fn2 = sinon.stub(TrustRepository.prototype, 'get').resolves([]); + const fn3 = sinon.stub(TrustRepository.prototype, 'create'); + sinon.stub(Wallet.prototype, 'checkDuplicateRequest'); await wallet.requestTrustFromAWallet( TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, wallet, @@ -109,73 +114,71 @@ describe("Wallet", () => { fn3.restore(); }); - describe("Request trust for sub wallet", () => { - + describe('Request trust for sub wallet', () => { it("To request sub wallet to which I don't have permission, throw 403", async () => { - sinon.stub(Wallet.prototype, "hasControlOver").resolves(false); + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(false); await jestExpect(async () => { - await wallet.requestTrustFromAWallet("send",wallet2, wallet3); + await wallet.requestTrustFromAWallet('send', wallet2, wallet3); }).rejects.toThrow(/permission.*actor/i); }); - it("Successful", async () => { - sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); - sinon.stub(TrustRepository.prototype, "create").resolves({}); - sinon.stub(Wallet.prototype, "checkDuplicateRequest"); - await wallet.requestTrustFromAWallet("send", wallet2, wallet3); + it('Successful', async () => { + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); + sinon.stub(TrustRepository.prototype, 'create').resolves({}); + sinon.stub(Wallet.prototype, 'checkDuplicateRequest'); + await wallet.requestTrustFromAWallet('send', wallet2, wallet3); }); }); }); - describe("Accept trust", () => { - - const wallet = new Wallet(uuid.v4()) - const wallet2 = new Wallet(uuid.v4()) - const trustId = uuid.v4() + describe('Accept trust', () => { + const wallet = new Wallet(uuid.v4()); + const wallet2 = new Wallet(uuid.v4()); + const trustId = uuid.v4(); const trustRelationship = { id: trustId, target_wallet_id: wallet.getId(), }; - it("accept but the requested trust whose target id is not me, throw 403", async () => { - - const fn1 = sinon.stub(Wallet.prototype, "getTrustRelationshipsRequestedToMe").returns([trustRelationship]); - const fn2 = sinon.stub(TrustRepository.prototype, "update"); - sinon.stub(Wallet.prototype, "checkManageCircle"); + it('accept but the requested trust whose target id is not me, throw 403', async () => { + const fn1 = sinon + .stub(Wallet.prototype, 'getTrustRelationshipsRequestedToMe') + .returns([trustRelationship]); + const fn2 = sinon.stub(TrustRepository.prototype, 'update'); + sinon.stub(Wallet.prototype, 'checkManageCircle'); await jestExpect(async () => { await wallet.acceptTrustRequestSentToMe(2); }).rejects.toThrow(/no permission/i); fn1.restore(); fn2.restore(); - }); - it("accept successfully", async () => { - - const fn1 = sinon.stub(Wallet.prototype, "getTrustRelationshipsRequestedToMe").returns([trustRelationship]); - const fn2 = sinon.stub(TrustRepository.prototype, "update"); - sinon.stub(Wallet.prototype, "checkManageCircle"); + it('accept successfully', async () => { + const fn1 = sinon + .stub(Wallet.prototype, 'getTrustRelationshipsRequestedToMe') + .returns([trustRelationship]); + const fn2 = sinon.stub(TrustRepository.prototype, 'update'); + sinon.stub(Wallet.prototype, 'checkManageCircle'); await wallet.acceptTrustRequestSentToMe(trustRelationship.id); fn1.restore(); fn2.restore(); - }); - }); - describe("Decline trust", () => { - - const wallet = new Wallet(uuid.v4()) - const wallet2 = new Wallet(uuid.v4()) - const trustId = uuid.v4() + describe('Decline trust', () => { + const wallet = new Wallet(uuid.v4()); + const wallet2 = new Wallet(uuid.v4()); + const trustId = uuid.v4(); const trustRelationship = { id: trustId, target_wallet_id: wallet.getId(), }; - it("decline but the requested trust whose target id is not me, throw 403", async () => { - const fn1 = sinon.stub(Wallet.prototype, "getTrustRelationshipsRequestedToMe").returns([trustRelationship]); - const fn2 = sinon.stub(TrustRepository.prototype, "update"); + it('decline but the requested trust whose target id is not me, throw 403', async () => { + const fn1 = sinon + .stub(Wallet.prototype, 'getTrustRelationshipsRequestedToMe') + .returns([trustRelationship]); + const fn2 = sinon.stub(TrustRepository.prototype, 'update'); await jestExpect(async () => { await wallet.declineTrustRequestSentToMe(2); }).rejects.toThrow(/no permission/i); @@ -183,28 +186,31 @@ describe("Wallet", () => { fn2.restore(); }); - it("decline successfully", async () => { - const fn1 = sinon.stub(Wallet.prototype, "getTrustRelationshipsRequestedToMe").returns([trustRelationship]); - const fn2 = sinon.stub(TrustRepository.prototype, "update"); + it('decline successfully', async () => { + const fn1 = sinon + .stub(Wallet.prototype, 'getTrustRelationshipsRequestedToMe') + .returns([trustRelationship]); + const fn2 = sinon.stub(TrustRepository.prototype, 'update'); await wallet.declineTrustRequestSentToMe(trustRelationship.id); fn1.restore(); fn2.restore(); }); }); - describe("Cancel trust request", () => { + describe('Cancel trust request', () => { + const wallet = new Wallet(uuid.v4()); + const wallet2 = new Wallet(uuid.v4()); + const trustId = uuid.v4(); - const wallet = new Wallet(uuid.v4()) - const wallet2 = new Wallet(uuid.v4()) - const trustId = uuid.v4() - - it("Try to cancel but the requested trust whose originator id is not me, throw 403", async () => { + it('Try to cancel but the requested trust whose originator id is not me, throw 403', async () => { const trustRelationship = { id: trustId, target_wallet_id: wallet.getId(), }; - const fn1 = sinon.stub(TrustRepository.prototype, "getById").returns(trustRelationship); - const fn2 = sinon.stub(TrustRepository.prototype, "update"); + const fn1 = sinon + .stub(TrustRepository.prototype, 'getById') + .returns(trustRelationship); + const fn2 = sinon.stub(TrustRepository.prototype, 'update'); await jestExpect(async () => { await wallet.cancelTrustRequestSentToMe(trustId); }).rejects.toThrow(/no permission/i); @@ -212,51 +218,57 @@ describe("Wallet", () => { fn2.restore(); }); - it("cancel successfully", async () => { + it('cancel successfully', async () => { const trustRelationship = { id: trustId, originator_wallet_id: wallet.getId(), }; - const fn1 = sinon.stub(TrustRepository.prototype, "getById").returns(trustRelationship); - const fn2 = sinon.stub(TrustRepository.prototype, "update"); + const fn1 = sinon + .stub(TrustRepository.prototype, 'getById') + .returns(trustRelationship); + const fn2 = sinon.stub(TrustRepository.prototype, 'update'); await wallet.cancelTrustRequestSentToMe(trustId); fn1.restore(); fn2.restore(); }); - it.skip("TODO try to cancel but the state is inpropricate, should throw 403", () => { - }); + it.skip('TODO try to cancel but the state is inpropricate, should throw 403', () => {}); }); - describe("hasTrust()", () => { - - const wallet = new Wallet(uuid.v4()) - const wallet2 = new Wallet(uuid.v4()) - const trustId = uuid.v4() + describe('hasTrust()', () => { + const wallet = new Wallet(uuid.v4()); + const wallet2 = new Wallet(uuid.v4()); + const trustId = uuid.v4(); const trustRelationship = { id: trustId, target_wallet_id: wallet.getId(), }; - it("has no trust", async () => { - const fn1 = sinon.stub(Wallet.prototype, "getTrustRelationshipsTrusted").resolves([]);//no relationship - const result = await wallet.hasTrust( - TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, - wallet, - wallet2, - ); + it('has no trust', async () => { + const fn1 = sinon + .stub(Wallet.prototype, 'getTrustRelationshipsTrusted') + .resolves([]); // no relationship + const result = await wallet.hasTrust( + TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, + wallet, + wallet2, + ); expect(result).eq(false); fn1.restore(); }); - it("has trust", async () => { - const fn1 = sinon.stub(Wallet.prototype, "getTrustRelationships").resolves([{ - request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, - type: TrustRelationship.ENTITY_TRUST_TYPE.send, - actor_wallet_id: wallet.getId(), - target_wallet_id: wallet2.getId(), - state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, - }]); + it('has trust', async () => { + const fn1 = sinon + .stub(Wallet.prototype, 'getTrustRelationships') + .resolves([ + { + request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, + type: TrustRelationship.ENTITY_TRUST_TYPE.send, + actor_wallet_id: wallet.getId(), + target_wallet_id: wallet2.getId(), + state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, + }, + ]); const result = await wallet.hasTrust( TrustRelationship.ENTITY_TRUST_TYPE.send, wallet, @@ -266,13 +278,17 @@ describe("Wallet", () => { fn1.restore(); }); - it("has trust with receive case", async () => { - const fn1 = sinon.stub(Wallet.prototype, "getTrustRelationshipsTrusted").resolves([{ - request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.receive, - type: TrustRelationship.ENTITY_TRUST_TYPE.send, - actor_wallet_id: wallet2.getId(), - target_wallet_id: wallet.getId(), - }]); + it('has trust with receive case', async () => { + const fn1 = sinon + .stub(Wallet.prototype, 'getTrustRelationshipsTrusted') + .resolves([ + { + request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.receive, + type: TrustRelationship.ENTITY_TRUST_TYPE.send, + actor_wallet_id: wallet2.getId(), + target_wallet_id: wallet.getId(), + }, + ]); const result = await wallet.hasTrust( TrustRelationship.ENTITY_TRUST_TYPE.send, wallet, @@ -281,20 +297,21 @@ describe("Wallet", () => { expect(result).eq(true); fn1.restore(); }); - }); - describe("Transfer", () => { - - const sender = new Wallet(uuid.v4()) - const receiver = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - - it("Given token uuid do not belongs to sender wallet, should throw 403", async () => { - const fn1 = sinon.stub(Token.prototype, "belongsTo").resolves(false); - await jestExpect(async () => { + describe('Transfer', () => { + const sender = new Wallet(uuid.v4()); + const receiver = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + + it('Given token uuid do not belongs to sender wallet, should throw 403', async () => { + const fn1 = sinon.stub(Token.prototype, 'belongsTo').resolves(false); + await jestExpect(async () => { await wallet.transfer(sender, receiver, [token]); }).rejects.toThrow(/belongs/); fn1.restore(); @@ -322,17 +339,18 @@ describe("Wallet", () => { // }); it("don't have trust, sender under control, should return transfer with pending state", async () => { - sinon.stub(Wallet.prototype, "isDeduct").resolves(false); - const fn3 = sinon.stub(Wallet.prototype, "hasControlOver"); + sinon.stub(Wallet.prototype, 'isDeduct').resolves(false); + const fn3 = sinon.stub(Wallet.prototype, 'hasControlOver'); fn3.onFirstCall().resolves(true); fn3.onSecondCall().resolves(false); - const fn0 = sinon.stub(Token.prototype, "belongsTo").resolves(true); - sinon.stub(Token.prototype, "beAbleToTransfer").resolves(true); - sinon.stub(TokenService.prototype, "pendingTransfer"); - const fn1 = sinon.stub(TransferRepository.prototype, "create").resolves({ + const fn0 = sinon.stub(Token.prototype, 'belongsTo').resolves(true); + sinon.stub(Token.prototype, 'beAbleToTransfer').resolves(true); + sinon.stub(TokenService.prototype, 'pendingTransfer'); + const fn1 = sinon.stub(TransferRepository.prototype, 'create').resolves({ id: 1, state: Transfer.STATE.pending, }); + const fn2 = sinon.stub(sender, "hasTrust").resolves(false); const transfer = await sender.transfer(sender, receiver, [token], false); expect(transfer).property("state").eq(Transfer.STATE.pending); @@ -351,16 +369,18 @@ describe("Wallet", () => { fn2.restore(); }); - //This shouldn't be able to pass anymore, because this is a deduct case, this case do not support yet, check the test for "deduct" + // This shouldn't be able to pass anymore, because this is a deduct case, this case do not support yet, check the test for "deduct" it.skip("don't have trust, receiver under control, should created a transfer request record", async () => { - const fn0 = sinon.stub(Token.prototype, "belongsTo").resolves(true); - const fn1 = sinon.stub(TransferRepository.prototype, "create").resolves({ + const fn0 = sinon.stub(Token.prototype, 'belongsTo').resolves(true); + const fn1 = sinon.stub(TransferRepository.prototype, 'create').resolves({ id: 1, state: Transfer.STATE.requested, }); + const fn2 = sinon.stub(wallet, "checkTrust").rejects(new HttpError(403)); const transfer = await wallet.transfer(sender, receiver, [token], false); expect(transfer).property("state").eq(Transfer.STATE.requested); + expect(fn1).to.have.been.calledWith({ originator_wallet_id: sender.getId(), source_wallet_id: receiver.getId(), @@ -370,42 +390,48 @@ describe("Wallet", () => { tokens: [token.id], }, claim: false + }); fn0.restore(); fn1.restore(); fn2.restore(); }); - //This shouldn't be able to pass anymore, because this is a deduct case, this case do not support yet, check the test for "deduct" - it.skip("have trust, should finish successfully", async () => { - const fn0 = sinon.stub(Token.prototype, "belongsTo").resolves(true); - const fn1 = sinon.stub(wallet, "checkTrust"); - const fn2 = sinon.stub(TransferRepository.prototype, "create"); - const fn3 = sinon.stub(Token.prototype, "completeTransfer"); + // This shouldn't be able to pass anymore, because this is a deduct case, this case do not support yet, check the test for "deduct" + it.skip('have trust, should finish successfully', async () => { + const fn0 = sinon.stub(Token.prototype, 'belongsTo').resolves(true); + const fn1 = sinon.stub(wallet, 'checkTrust'); + const fn2 = sinon.stub(TransferRepository.prototype, 'create'); + const fn3 = sinon.stub(Token.prototype, 'completeTransfer'); await wallet.transfer(sender, receiver, [token]); - expect(fn2).calledWith(sinon.match({ - state: Transfer.STATE.completed, - })); + expect(fn2).calledWith( + sinon.match({ + state: Transfer.STATE.completed, + }), + ); expect(fn3).calledWith(); fn0.restore(); fn1.restore(); fn2.restore(); fn3.restore(); }); - }); - describe("Bundle transfer", () => { - - const sender = new Wallet(uuid.v4()) - const receiver = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - const transferId = uuid.v4() + describe('Bundle transfer', () => { + const sender = new Wallet(uuid.v4()); + const receiver = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + const transferId = uuid.v4(); it("Sender doesn't have enough tokens to send, should throw 403", async () => { - const fn0 = sinon.stub(TokenService.prototype, "countTokenByWallet").resolves(1); + const fn0 = sinon + .stub(TokenService.prototype, 'countTokenByWallet') + .resolves(1); await jestExpect(async () => { await wallet.transferBundle(sender, receiver, 2); }).rejects.toThrow(/enough/); @@ -413,16 +439,18 @@ describe("Wallet", () => { }); it("don't have trust, sender under control, should created a transfer pending record", async () => { + const fn0 = sinon.stub(TokenService.prototype, "countTokenByWallet").resolves(1); const fn4 = sinon.stub(TokenService.prototype, "countNotClaimedTokenByWallet").resolves(1); const fn1 = sinon.stub(TransferRepository.prototype, "create").resolves({ id: transferId, state: Transfer.STATE.pending, }); - sinon.stub(Wallet.prototype, "isDeduct").resolves(false); - const fn3 = sinon.stub(Wallet.prototype, "hasControlOver"); + sinon.stub(Wallet.prototype, 'isDeduct').resolves(false); + const fn3 = sinon.stub(Wallet.prototype, 'hasControlOver'); fn3.onFirstCall().resolves(true); fn3.onSecondCall().resolves(false); + const fn2 = sinon.stub(sender, "hasTrust").resolves(false); const transfer = await sender.transferBundle(sender, receiver, 1, false); expect(transfer).property("state").eq(Transfer.STATE.pending); @@ -434,7 +462,7 @@ describe("Wallet", () => { parameters: { bundle: { bundleSize: 1, - } + }, }, claim: false, }); @@ -451,10 +479,11 @@ describe("Wallet", () => { id: transferId, state: Transfer.STATE.requested, }); - sinon.stub(Wallet.prototype, "isDeduct").resolves(false); - const fn3 = sinon.stub(Wallet.prototype, "hasControlOver"); + sinon.stub(Wallet.prototype, 'isDeduct').resolves(false); + const fn3 = sinon.stub(Wallet.prototype, 'hasControlOver'); fn3.onFirstCall().resolves(false); fn3.onSecondCall().resolves(true); + const fn2 = sinon.stub(receiver, "hasTrust").resolves(false); const transfer = await receiver.transferBundle(sender, receiver, 1, false); expect(transfer).property("state").eq(Transfer.STATE.requested); @@ -467,7 +496,7 @@ describe("Wallet", () => { parameters: { bundle: { bundleSize: 1, - } + }, }, }); fn0.restore(); @@ -476,6 +505,7 @@ describe("Wallet", () => { fn4.restore(); }); + it("have trust, not deduct, should finish successfully", async () => { const fn0 = sinon.stub(TokenService.prototype, "countTokenByWallet").resolves(1); const fn5 = sinon.stub(TokenService.prototype, "countNotClaimedTokenByWallet").resolves(1); @@ -491,6 +521,7 @@ describe("Wallet", () => { expect(fn2).calledWith(sinon.match({ state: Transfer.STATE.completed, })); + expect(fn3).calledWith(); fn0.restore(); fn1.restore(); @@ -500,6 +531,7 @@ describe("Wallet", () => { fn5.restore(); }); + it("have trust, is deduct, should pending", async () => { const fn0 = sinon.stub(TokenService.prototype, "countTokenByWallet").resolves(1); const fn6 = sinon.stub(TokenService.prototype, "countNotClaimedTokenByWallet").resolves(1); @@ -517,73 +549,85 @@ describe("Wallet", () => { expect(fn2).calledWith(sinon.match({ state: Transfer.STATE.requested, })); + fn0.restore(); fn1.restore(); fn2.restore(); fn3.restore(); fn4.restore(); }); - }); - describe("getPendingTransfers", () => { - - const sender = new Wallet(uuid.v4()) - const receiver = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - - it("getPendingTransfers", async () => { - const fn1 = sinon.stub(TransferRepository.prototype, "getPendingTransfers").resolves([{id:uuid.v4()}]); + describe('getPendingTransfers', () => { + const sender = new Wallet(uuid.v4()); + const receiver = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + + it('getPendingTransfers', async () => { + const fn1 = sinon + .stub(TransferRepository.prototype, 'getPendingTransfers') + .resolves([{ id: uuid.v4() }]); const result = await wallet.getPendingTransfers(); expect(result).lengthOf(1); fn1.restore(); }); }); - describe("acceptTransfer", () => { - - const sender = new Wallet(uuid.v4()) - const receiver = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - const transferId = uuid.v4() + describe('acceptTransfer', () => { + const sender = new Wallet(uuid.v4()); + const receiver = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + const transferId = uuid.v4(); it("can not accept transfer who's state isn't pending", async () => { - sinon.stub(TransferRepository.prototype, "getById").resolves({ + sinon.stub(TransferRepository.prototype, 'getById').resolves({ id: transferId, state: Transfer.STATE.requested, - }); - sinon.stub(TransferRepository.prototype, "update"); - sinon.stub(TokenService.prototype, "getTokensByPendingTransferId").resolves([token]); - sinon.stub(Token.prototype, "completeTransfer"); - sinon.stub(WalletService.prototype, "getById"); - sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); + }); + sinon.stub(TransferRepository.prototype, 'update'); + sinon + .stub(TokenService.prototype, 'getTokensByPendingTransferId') + .resolves([token]); + sinon.stub(Token.prototype, 'completeTransfer'); + sinon.stub(WalletService.prototype, 'getById'); + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); await jestExpect(async () => { await wallet.acceptTransfer(transferId); }).rejects.toThrow(/pending/); }); - it("acceptTransfer", async () => { + it('acceptTransfer', async () => { const walletId1 = uuid.v4(); const walletId2 = uuid.v4(); - const fn1 = sinon.stub(TransferRepository.prototype, "getById").resolves({ + const fn1 = sinon.stub(TransferRepository.prototype, 'getById').resolves({ id: transferId, state: Transfer.STATE.pending, source_wallet_id: walletId1, destination_wallet_id: walletId2, - }); - const fn2 = sinon.stub(TransferRepository.prototype, "update"); - const fn3 = sinon.stub(TokenService.prototype, "getTokensByPendingTransferId").resolves([ token ]); - const fn4 = sinon.stub(TokenService.prototype, "completeTransfer"); - const fn5 = sinon.stub(WalletService.prototype, "getById"); - const fn6 = sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); + }); + const fn2 = sinon.stub(TransferRepository.prototype, 'update'); + const fn3 = sinon + .stub(TokenService.prototype, 'getTokensByPendingTransferId') + .resolves([token]); + const fn4 = sinon.stub(TokenService.prototype, 'completeTransfer'); + const fn5 = sinon.stub(WalletService.prototype, 'getById'); + const fn6 = sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); await wallet.acceptTransfer(transferId); - expect(fn2).calledWith(sinon.match({ - state: Transfer.STATE.completed, - })); + expect(fn2).calledWith( + sinon.match({ + state: Transfer.STATE.completed, + }), + ); expect(fn4).calledWith(); fn1.restore(); fn2.restore(); @@ -593,26 +637,30 @@ describe("Wallet", () => { fn6.restore(); }); - it("acceptTransfer with bundle", async () => { - const fn1 = sinon.stub(TransferRepository.prototype, "getById").resolves({ + it('acceptTransfer with bundle', async () => { + const fn1 = sinon.stub(TransferRepository.prototype, 'getById').resolves({ id: transferId, source_wallet_id: receiver.getId(), state: Transfer.STATE.pending, parameters: { bundle: { bundleSize: 1, - } + }, }, - }); - const fn2 = sinon.stub(TransferRepository.prototype, "update"); - const fn4 = sinon.stub(TokenService.prototype, "completeTransfer"); - const fn5 = sinon.stub(TokenService.prototype, "getTokensByBundle").resolves([ token ]); - const fn6 = sinon.stub(WalletService.prototype, "getById"); - const fn7 = sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); + }); + const fn2 = sinon.stub(TransferRepository.prototype, 'update'); + const fn4 = sinon.stub(TokenService.prototype, 'completeTransfer'); + const fn5 = sinon + .stub(TokenService.prototype, 'getTokensByBundle') + .resolves([token]); + const fn6 = sinon.stub(WalletService.prototype, 'getById'); + const fn7 = sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); await receiver.acceptTransfer(transferId); - expect(fn2).calledWith(sinon.match({ - state: Transfer.STATE.completed, - })); + expect(fn2).calledWith( + sinon.match({ + state: Transfer.STATE.completed, + }), + ); expect(fn5).calledWith(sinon.match.any, 1); expect(fn4).calledWith(); fn1.restore(); @@ -624,46 +672,56 @@ describe("Wallet", () => { }); }); - describe("declineTransfer", () => { - - const wallet = new Wallet(uuid.v4()) - const sender = new Wallet(uuid.v4()) - const receiver = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - const transferId = uuid.v4() - - it("fail to decline if transfer state is neither the pending nor requested", async () => { - sinon.stub(TransferRepository.prototype, "getById").resolves({id:transferId}); - sinon.stub(TransferRepository.prototype, "update"); - sinon.stub(TokenService.prototype, "getTokensByPendingTransferId").resolves([token.id]); - sinon.stub(Token.prototype, "cancelTransfer"); - sinon.stub(WalletService.prototype, "getById"); - sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); + describe('declineTransfer', () => { + const wallet = new Wallet(uuid.v4()); + const sender = new Wallet(uuid.v4()); + const receiver = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + const transferId = uuid.v4(); + + it('fail to decline if transfer state is neither the pending nor requested', async () => { + sinon + .stub(TransferRepository.prototype, 'getById') + .resolves({ id: transferId }); + sinon.stub(TransferRepository.prototype, 'update'); + sinon + .stub(TokenService.prototype, 'getTokensByPendingTransferId') + .resolves([token.id]); + sinon.stub(Token.prototype, 'cancelTransfer'); + sinon.stub(WalletService.prototype, 'getById'); + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); await jestExpect(async () => { await wallet.declineTransfer(transferId); }).rejects.toThrow(/state/); }); it("Can decline a 'pending' transfer for a managed wallet", async () => { - const fn1 = sinon.stub(TransferRepository.prototype, "getById").resolves({ + const fn1 = sinon.stub(TransferRepository.prototype, 'getById').resolves({ id: transferId, state: Transfer.STATE.pending, source_wallet_id: sender.getId(), destination_wallet_id: receiver.getId(), - }); - const fn2 = sinon.stub(TransferRepository.prototype, "update"); - const fn3 = sinon.stub(TokenService.prototype, "getTokensByPendingTransferId").resolves([token]); - const fn4 = sinon.stub(TokenService.prototype, "cancelTransfer"); - const fn5 = sinon.stub(WalletService.prototype, "getById"); + }); + const fn2 = sinon.stub(TransferRepository.prototype, 'update'); + const fn3 = sinon + .stub(TokenService.prototype, 'getTokensByPendingTransferId') + .resolves([token]); + const fn4 = sinon.stub(TokenService.prototype, 'cancelTransfer'); + const fn5 = sinon.stub(WalletService.prototype, 'getById'); fn5.onCall(0).resolves(sender); fn5.onCall(1).resolves(receiver); - const fn6 = sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); + const fn6 = sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); await wallet.declineTransfer(transferId); - expect(fn2).calledWith(sinon.match({ - state: Transfer.STATE.cancelled, - })); + expect(fn2).calledWith( + sinon.match({ + state: Transfer.STATE.cancelled, + }), + ); expect(fn4).calledWith(); expect(fn6).calledWith(receiver); fn1.restore(); @@ -675,23 +733,27 @@ describe("Wallet", () => { }); it("Can decline a 'requested' transfer for a managed wallet", async () => { - const fn1 = sinon.stub(TransferRepository.prototype, "getById").resolves({ - id:transferId, + const fn1 = sinon.stub(TransferRepository.prototype, 'getById').resolves({ + id: transferId, state: Transfer.STATE.requested, source_wallet_id: sender.getId(), destination_wallet_id: receiver.getId(), - }); - const fn2 = sinon.stub(TransferRepository.prototype, "update"); - const fn3 = sinon.stub(TokenService.prototype, "getTokensByPendingTransferId").resolves([token]); - const fn4 = sinon.stub(TokenService.prototype, "cancelTransfer"); - const fn5 = sinon.stub(WalletService.prototype, "getById"); + }); + const fn2 = sinon.stub(TransferRepository.prototype, 'update'); + const fn3 = sinon + .stub(TokenService.prototype, 'getTokensByPendingTransferId') + .resolves([token]); + const fn4 = sinon.stub(TokenService.prototype, 'cancelTransfer'); + const fn5 = sinon.stub(WalletService.prototype, 'getById'); fn5.onCall(0).resolves(sender); fn5.onCall(1).resolves(receiver); - const fn6 = sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); + const fn6 = sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); await wallet.declineTransfer(transferId); - expect(fn2).calledWith(sinon.match({ - state: Transfer.STATE.cancelled, - })); + expect(fn2).calledWith( + sinon.match({ + state: Transfer.STATE.cancelled, + }), + ); expect(fn4).calledWith(); expect(fn6).calledWith(sender); fn1.restore(); @@ -703,34 +765,40 @@ describe("Wallet", () => { }); }); - describe("cancelTransfer", () => { - - const wallet = new Wallet(uuid.v4()) - const wallet2 = new Wallet(uuid.v4()) - const wallet3 = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - const transferId = uuid.v4() + describe('cancelTransfer', () => { + const wallet = new Wallet(uuid.v4()); + const wallet2 = new Wallet(uuid.v4()); + const wallet3 = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + const transferId = uuid.v4(); it("Can cancel a 'pending' transfer", async () => { - const fn1 = sinon.stub(TransferRepository.prototype, "getById").resolves({ + const fn1 = sinon.stub(TransferRepository.prototype, 'getById').resolves({ id: transferId, state: Transfer.STATE.pending, source_wallet_id: wallet2.getId(), destination_wallet_id: wallet3.getId(), - }); - const fn2 = sinon.stub(TransferRepository.prototype, "update"); - const fn3 = sinon.stub(WalletService.prototype, "getById"); + }); + const fn2 = sinon.stub(TransferRepository.prototype, 'update'); + const fn3 = sinon.stub(WalletService.prototype, 'getById'); fn3.onCall(0).resolves(wallet2); fn3.onCall(1).resolves(wallet3); - const fn4 = sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); - sinon.stub(TokenService.prototype, "getTokensByPendingTransferId").resolves([]); - sinon.stub(TokenService.prototype, "cancelTransfer"); + const fn4 = sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); + sinon + .stub(TokenService.prototype, 'getTokensByPendingTransferId') + .resolves([]); + sinon.stub(TokenService.prototype, 'cancelTransfer'); await wallet.cancelTransfer(transferId); - expect(fn2).calledWith(sinon.match({ - state: Transfer.STATE.cancelled, - })); + expect(fn2).calledWith( + sinon.match({ + state: Transfer.STATE.cancelled, + }), + ); expect(fn4).calledWith(wallet2); fn1.restore(); fn2.restore(); @@ -739,23 +807,27 @@ describe("Wallet", () => { }); it("Can cancel a 'requested' transfer", async () => { - const fn1 = sinon.stub(TransferRepository.prototype, "getById").resolves({ + const fn1 = sinon.stub(TransferRepository.prototype, 'getById').resolves({ id: transferId, state: Transfer.STATE.requested, source_wallet_id: wallet2.getId(), destination_wallet_id: wallet3.getId(), - }); - const fn2 = sinon.stub(TransferRepository.prototype, "update"); - const fn3 = sinon.stub(WalletService.prototype, "getById"); + }); + const fn2 = sinon.stub(TransferRepository.prototype, 'update'); + const fn3 = sinon.stub(WalletService.prototype, 'getById'); fn3.onCall(0).resolves(wallet2); fn3.onCall(1).resolves(wallet3); - const fn4 = sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); - sinon.stub(TokenService.prototype, "getTokensByPendingTransferId").resolves([]); - sinon.stub(TokenService.prototype, "cancelTransfer"); + const fn4 = sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); + sinon + .stub(TokenService.prototype, 'getTokensByPendingTransferId') + .resolves([]); + sinon.stub(TokenService.prototype, 'cancelTransfer'); await wallet.cancelTransfer(1); - expect(fn2).calledWith(sinon.match({ - state: Transfer.STATE.cancelled, - })); + expect(fn2).calledWith( + sinon.match({ + state: Transfer.STATE.cancelled, + }), + ); expect(fn4).calledWith(wallet3); fn1.restore(); fn2.restore(); @@ -764,26 +836,30 @@ describe("Wallet", () => { }); }); - describe("fulfillTransfer", () => { - - const wallet = new Wallet(uuid.v4()) - const wallet2 = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - const transferId = uuid.v4() - - it("fulfillTransfer successfully", async () => { - const fn1 = sinon.stub(TransferRepository.prototype, "getById").resolves({ + describe('fulfillTransfer', () => { + const wallet = new Wallet(uuid.v4()); + const wallet2 = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + const transferId = uuid.v4(); + + it('fulfillTransfer successfully', async () => { + const fn1 = sinon.stub(TransferRepository.prototype, 'getById').resolves({ id: transferId, source_wallet_id: wallet.getId(), state: Transfer.STATE.requested, - }); - const fn2 = sinon.stub(TransferRepository.prototype, "update"); - const fn3 = sinon.stub(WalletService.prototype, "getById"); - const fn4 = sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); - sinon.stub(TokenService.prototype, "completeTransfer"); - sinon.stub(TokenService.prototype, "getTokensByPendingTransferId").resolves([]); + }); + const fn2 = sinon.stub(TransferRepository.prototype, 'update'); + const fn3 = sinon.stub(WalletService.prototype, 'getById'); + const fn4 = sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); + sinon.stub(TokenService.prototype, 'completeTransfer'); + sinon + .stub(TokenService.prototype, 'getTokensByPendingTransferId') + .resolves([]); await wallet.fulfillTransfer(transferId); fn1.restore(); fn2.restore(); @@ -792,12 +868,16 @@ describe("Wallet", () => { }); it("have no control over the transfer's sender , should throw 403 no permission", async () => { - const fn1 = sinon.stub(TransferRepository.prototype, "getById").resolves([{ - id: transferId, - source_wallet_id: wallet2.getId(), - }]); - const fn2 = sinon.stub(WalletService.prototype, "getById"); - const fn3 = sinon.stub(Wallet.prototype, "hasControlOver").resolves(false); + const fn1 = sinon.stub(TransferRepository.prototype, 'getById').resolves([ + { + id: transferId, + source_wallet_id: wallet2.getId(), + }, + ]); + const fn2 = sinon.stub(WalletService.prototype, 'getById'); + const fn3 = sinon + .stub(Wallet.prototype, 'hasControlOver') + .resolves(false); await jestExpect(async () => { await wallet.fulfillTransfer(transferId); }).rejects.toThrow(/permission/); @@ -807,12 +887,12 @@ describe("Wallet", () => { }); it("the transfer's state is not requested, should throw 403 forbidden", async () => { - const fn1 = sinon.stub(TransferRepository.prototype, "getById").resolves({ + const fn1 = sinon.stub(TransferRepository.prototype, 'getById').resolves({ id: transferId, source_wallet_id: wallet.getId(), - }); - const fn2 = sinon.stub(WalletService.prototype, "getById"); - const fn3 = sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); + }); + const fn2 = sinon.stub(WalletService.prototype, 'getById'); + const fn3 = sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); await jestExpect(async () => { await wallet.fulfillTransfer(transferId); }).rejects.toThrow(/forbidden/); @@ -822,223 +902,255 @@ describe("Wallet", () => { }); }); - describe("fulfillTransferWithTokens", () => { - - const wallet = new Wallet(uuid.v4()) - const wallet2 = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - const token2 = new Token({ - id: uuid.v4(), - }, session); - const transferId = uuid.v4() - - it("fulfillTransfer successfully", async () => { - sinon.stub(TransferRepository.prototype, "getById").resolves({ - id:1, + describe('fulfillTransferWithTokens', () => { + const wallet = new Wallet(uuid.v4()); + const wallet2 = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + const token2 = new Token( + { + id: uuid.v4(), + }, + session, + ); + const transferId = uuid.v4(); + + it('fulfillTransfer successfully', async () => { + sinon.stub(TransferRepository.prototype, 'getById').resolves({ + id: 1, source_wallet_id: wallet.getId(), state: Transfer.STATE.requested, - parameters:{ + parameters: { bundle: { bundleSize: 1, - } - } - }); - sinon.stub(TransferRepository.prototype, "update"); - sinon.stub(WalletService.prototype, "getById"); - sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); - sinon.stub(Token.prototype, "toJSON").resolves({uuid:"xxx"}); - sinon.stub(Token.prototype, "belongsTo").resolves(true); - sinon.stub(TokenService.prototype, "completeTransfer"); + }, + }, + }); + sinon.stub(TransferRepository.prototype, 'update'); + sinon.stub(WalletService.prototype, 'getById'); + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); + sinon.stub(Token.prototype, 'toJSON').resolves({ uuid: 'xxx' }); + sinon.stub(Token.prototype, 'belongsTo').resolves(true); + sinon.stub(TokenService.prototype, 'completeTransfer'); await wallet.fulfillTransferWithTokens(1, [token]); }); - it("Should not set tokens for non-bundle case", async () => { - sinon.stub(TransferRepository.prototype, "getById").resolves({ - id:1, + it('Should not set tokens for non-bundle case', async () => { + sinon.stub(TransferRepository.prototype, 'getById').resolves({ + id: 1, source_wallet_id: wallet.getId(), state: Transfer.STATE.requested, - parameters:{ - } - }); - sinon.stub(TransferRepository.prototype, "update"); - sinon.stub(WalletService.prototype, "getById"); - sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); + parameters: {}, + }); + sinon.stub(TransferRepository.prototype, 'update'); + sinon.stub(WalletService.prototype, 'getById'); + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); await jestExpect(async () => { await wallet.fulfillTransferWithTokens(1, [token]); }).rejects.toThrow(/no need/i); }); - it("Too many tokens", async () => { - sinon.stub(TransferRepository.prototype, "getById").resolves({ - id:1, + it('Too many tokens', async () => { + sinon.stub(TransferRepository.prototype, 'getById').resolves({ + id: 1, source_wallet_id: wallet.getId(), state: Transfer.STATE.requested, - parameters:{ + parameters: { bundle: { bundleSize: 1, - } - } - }); - sinon.stub(TransferRepository.prototype, "update"); - sinon.stub(WalletService.prototype, "getById"); - sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); - sinon.stub(Token.prototype, "toJSON").resolves({uuid:"xxx"}); - sinon.stub(Token.prototype, "belongsTo").resolves(true); - sinon.stub(Token.prototype, "completeTransfer"); + }, + }, + }); + sinon.stub(TransferRepository.prototype, 'update'); + sinon.stub(WalletService.prototype, 'getById'); + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); + sinon.stub(Token.prototype, 'toJSON').resolves({ uuid: 'xxx' }); + sinon.stub(Token.prototype, 'belongsTo').resolves(true); + sinon.stub(Token.prototype, 'completeTransfer'); await jestExpect(async () => { await wallet.fulfillTransferWithTokens(1, [token, token2]); }).rejects.toThrow(/too many/i); }); - it("Too few tokens", async () => { - sinon.stub(TransferRepository.prototype, "getById").resolves({ - id:1, + it('Too few tokens', async () => { + sinon.stub(TransferRepository.prototype, 'getById').resolves({ + id: 1, source_wallet_id: wallet.getId(), state: Transfer.STATE.requested, - parameters:{ + parameters: { bundle: { bundleSize: 1, - } - } - }); - sinon.stub(TransferRepository.prototype, "update"); - sinon.stub(WalletService.prototype, "getById"); - sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); + }, + }, + }); + sinon.stub(TransferRepository.prototype, 'update'); + sinon.stub(WalletService.prototype, 'getById'); + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); await jestExpect(async () => { await wallet.fulfillTransferWithTokens(1, []); }).rejects.toThrow(/too few/i); }); - it("Specified token do not belongs to the wallet", async () => { - sinon.stub(TransferRepository.prototype, "getById").resolves({ - id:transferId, + it('Specified token do not belongs to the wallet', async () => { + sinon.stub(TransferRepository.prototype, 'getById').resolves({ + id: transferId, source_wallet_id: wallet.getId(), state: Transfer.STATE.requested, - parameters:{ + parameters: { bundle: { bundleSize: 1, - } - } - }); - sinon.stub(TransferRepository.prototype, "update"); - sinon.stub(WalletService.prototype, "getById"); - sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); - sinon.stub(Token.prototype, "toJSON").resolves({uuid:"xxx"}); - sinon.stub(Token.prototype, "belongsTo").resolves(false); + }, + }, + }); + sinon.stub(TransferRepository.prototype, 'update'); + sinon.stub(WalletService.prototype, 'getById'); + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); + sinon.stub(Token.prototype, 'toJSON').resolves({ uuid: 'xxx' }); + sinon.stub(Token.prototype, 'belongsTo').resolves(false); await jestExpect(async () => { await wallet.fulfillTransferWithTokens(transferId, [token]); }).rejects.toThrow(/belongs to/i); }); - }); - describe("getTransfers", () => { - - const wallet = new Wallet(uuid.v4()) - const wallet2 = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - const transferId = uuid.v4() - - it("getTransfers", async () => { - const fn1 = sinon.stub(TransferRepository.prototype, "getByFilter").resolves([{id:transferId}]); + describe('getTransfers', () => { + const wallet = new Wallet(uuid.v4()); + const wallet2 = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + const transferId = uuid.v4(); + + it('getTransfers', async () => { + const fn1 = sinon + .stub(TransferRepository.prototype, 'getByFilter') + .resolves([{ id: transferId }]); const result = await wallet.getTransfers( Transfer.STATE.requested, wallet2, ); expect(result).lengthOf(1); - expect(fn1).calledWith( - { - and: [{ + expect(fn1).calledWith({ + and: [ + { or: [ { source_wallet_id: wallet.getId(), - },{ + }, + { destination_wallet_id: wallet.getId(), - },{ + }, + { originator_wallet_id: wallet.getId(), - } + }, ], - },{ + }, + { state: Transfer.STATE.requested, - },{ + }, + { or: [ { source_wallet_id: wallet2.getId(), - },{ + }, + { destination_wallet_id: wallet2.getId(), - },{ + }, + { originator_wallet_id: wallet2.getId(), - } + }, ], - }] - } - ); + }, + ], + }); fn1.restore(); }); - }); - describe("hasControlOver", () => { - - const wallet = new Wallet(uuid.v4()) - const wallet2 = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - const transferId = uuid.v4() - - it("hasControlOver should pass if it is the same wallet", async () => { - const result = await wallet.hasControlOver(wallet); + describe('hasControlOver', () => { + const wallet = new Wallet(uuid.v4()); + const wallet2 = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + const transferId = uuid.v4(); + + it('hasControlOver should pass if it is the same wallet', async () => { + const result = await wallet.hasControlOver(wallet); expect(result).eq(true); }); - it("hasControlOver should pass if manage/yield trust exists", async () => { - const fn = sinon.stub(TrustRepository.prototype, "getByFilter").resolves([{}]); - const result = await wallet.hasControlOver(wallet2); + it('hasControlOver should pass if manage/yield trust exists', async () => { + const fn = sinon + .stub(TrustRepository.prototype, 'getByFilter') + .resolves([{}]); + const result = await wallet.hasControlOver(wallet2); expect(result).eq(true); expect(fn).calledWith({ or: [ { - and: [{ - actor_wallet_id: wallet.getId(), - },{ - request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.manage, - },{ - target_wallet_id: wallet2.getId(), - },{ - state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, - }], - },{ - and: [{ - actor_wallet_id: wallet2.getId(), - },{ - request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.yield, - },{ - target_wallet_id: wallet.getId(), - },{ - state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, - }] - } - ] + and: [ + { + actor_wallet_id: wallet.getId(), + }, + { + request_type: + TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.manage, + }, + { + target_wallet_id: wallet2.getId(), + }, + { + state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, + }, + ], + }, + { + and: [ + { + actor_wallet_id: wallet2.getId(), + }, + { + request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.yield, + }, + { + target_wallet_id: wallet.getId(), + }, + { + state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, + }, + ], + }, + ], }); }); }); - describe("getTrustRelationships", () => { - - const wallet = new Wallet(uuid.v4()) - const wallet2 = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - const trustId = uuid.v4() - - it("successfully", async () => { - const fn = sinon.stub(TrustRepository.prototype, "getByFilter").resolves([{id:trustId}]); + describe('getTrustRelationships', () => { + const wallet = new Wallet(uuid.v4()); + const wallet2 = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + const trustId = uuid.v4(); + + it('successfully', async () => { + const fn = sinon + .stub(TrustRepository.prototype, 'getByFilter') + .resolves([{ id: trustId }]); const result = await wallet.getTrustRelationships( TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, TrustRelationship.ENTITY_TRUST_TYPE.send, @@ -1046,237 +1158,270 @@ describe("Wallet", () => { ); expect(result).lengthOf(1); expect(fn).calledWith({ - and: [{ - state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, - },{ - type: TrustRelationship.ENTITY_TRUST_TYPE.send, - },{ - request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, - },{ - or: [{ - actor_wallet_id: wallet.getId(), - },{ - target_wallet_id: wallet.getId(), - },{ - originator_wallet_id: wallet.getId(), - }] - }] + and: [ + { + state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, + }, + { + type: TrustRelationship.ENTITY_TRUST_TYPE.send, + }, + { + request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, + }, + { + or: [ + { + actor_wallet_id: wallet.getId(), + }, + { + target_wallet_id: wallet.getId(), + }, + { + originator_wallet_id: wallet.getId(), + }, + ], + }, + ], }); fn.restore(); }); - it("without filters", async () => { - const fn = sinon.stub(TrustRepository.prototype, "getByFilter").resolves([{id:trustId}]); + it('without filters', async () => { + const fn = sinon + .stub(TrustRepository.prototype, 'getByFilter') + .resolves([{ id: trustId }]); const result = await wallet.getTrustRelationships(); expect(result).lengthOf(1); expect(fn).calledWith({ - and: [{ - or: [{ - actor_wallet_id: wallet.getId(), - },{ - target_wallet_id: wallet.getId(), - },{ - originator_wallet_id: wallet.getId(), - }] - }] + and: [ + { + or: [ + { + actor_wallet_id: wallet.getId(), + }, + { + target_wallet_id: wallet.getId(), + }, + { + originator_wallet_id: wallet.getId(), + }, + ], + }, + ], }); fn.restore(); }); }); - describe("Deduct", () => { - - const wallet = new Wallet({id: uuid.v4()}) //TODO: should create class MockWallet that does not use repository - const sender = new Wallet(uuid.v4()) - const receiver = new Wallet(uuid.v4()) - const token = new Token({ - id: uuid.v4(), - }, session); - - it("the sender is me, should return false", async () => { + describe('Deduct', () => { + const wallet = new Wallet({ id: uuid.v4() }); // TODO: should create class MockWallet that does not use repository + const sender = new Wallet(uuid.v4()); + const receiver = new Wallet(uuid.v4()); + const token = new Token( + { + id: uuid.v4(), + }, + session, + ); + + it('the sender is me, should return false', async () => { const result = await wallet.isDeduct(wallet, receiver); expect(result).eq(false); }); - it("The sender is my sub wallet, should return false", async () => { - sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); + it('The sender is my sub wallet, should return false', async () => { + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); const result = await wallet.isDeduct(sender, receiver); expect(result).eq(false); }); // TODO: deduction is not supported yet it.skip("The sender isn't my sub wallet, should throw 403", async () => { - sinon.stub(Wallet.prototype, "hasControlOver").resolves(false); + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(false); const result = await wallet.isDeduct(sender, receiver); expect(result).eq(true); }); }); - describe("getSubWallet", () => { - - const wallet = new Wallet(uuid.v4()) - const subWallet = new Wallet(uuid.v4()) + describe('getSubWallet', () => { + const wallet = new Wallet(uuid.v4()); + const subWallet = new Wallet(uuid.v4()); - it("get sub wallet successfully", async () => { - sinon.stub(Wallet.prototype, "getTrustRelationships").resolves([{ - actor_wallet_id: wallet.getId(), - target_wallet_id: subWallet.getId(), - request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.manage, - state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, - }]); - sinon.stub(WalletService.prototype, "getById").resolves(subWallet); + it('get sub wallet successfully', async () => { + sinon.stub(Wallet.prototype, 'getTrustRelationships').resolves([ + { + actor_wallet_id: wallet.getId(), + target_wallet_id: subWallet.getId(), + request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.manage, + state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, + }, + ]); + sinon.stub(WalletService.prototype, 'getById').resolves(subWallet); const wallets = await wallet.getSubWallets(); expect(wallets).lengthOf(1); }); - it("get sub wallet which is state of yield", async () => { - sinon.stub(Wallet.prototype, "getTrustRelationships").resolves([{ - actor_wallet_id: subWallet.getId(), - target_wallet_id: wallet.getId(), - request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.yield, - state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, - }]); - sinon.stub(WalletService.prototype, "getById").resolves(subWallet); + it('get sub wallet which is state of yield', async () => { + sinon.stub(Wallet.prototype, 'getTrustRelationships').resolves([ + { + actor_wallet_id: subWallet.getId(), + target_wallet_id: wallet.getId(), + request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.yield, + state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, + }, + ]); + sinon.stub(WalletService.prototype, 'getById').resolves(subWallet); const wallets = await wallet.getSubWallets(); expect(wallets).lengthOf(1); }); }); - describe("getTrustRelationshipsRequestedToMe", () => { - + describe('getTrustRelationshipsRequestedToMe', () => { const wallet = new Wallet(uuid.v4()); const subWallet = new Wallet(uuid.v4()); - const wallet2 = new Wallet(uuid.v4()) + const wallet2 = new Wallet(uuid.v4()); - it("get one", async () => { - sinon.stub(Wallet.prototype, "getSubWallets").resolves([]); - sinon.stub(Wallet.prototype, "getTrustRelationships").resolves([{ - actor_wallet_id: wallet2.getId(), - target_wallet_id: wallet.getId(), - request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, - }]); - const list = await wallet.getTrustRelationshipsRequestedToMe() + it('get one', async () => { + sinon.stub(Wallet.prototype, 'getSubWallets').resolves([]); + sinon.stub(Wallet.prototype, 'getTrustRelationships').resolves([ + { + actor_wallet_id: wallet2.getId(), + target_wallet_id: wallet.getId(), + request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, + }, + ]); + const list = await wallet.getTrustRelationshipsRequestedToMe(); expect(list).lengthOf(1); }); - it("get one requested to my sub wallet", async () => { - sinon.stub(Wallet.prototype, "getSubWallets").resolves([subWallet]); - const fn = sinon.stub(Wallet.prototype, "getTrustRelationships") - fn.onCall(0).resolves([{ - actor_wallet_id: wallet2.getId(), - target_wallet_id: wallet.getId(), - request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, - }]); - fn.onCall(1).resolves([{ - actor_wallet_id: wallet2.getId(), - target_wallet_id: subWallet.getId(), - request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, - }]); - const list = await wallet.getTrustRelationshipsRequestedToMe() + it('get one requested to my sub wallet', async () => { + sinon.stub(Wallet.prototype, 'getSubWallets').resolves([subWallet]); + const fn = sinon.stub(Wallet.prototype, 'getTrustRelationships'); + fn.onCall(0).resolves([ + { + actor_wallet_id: wallet2.getId(), + target_wallet_id: wallet.getId(), + request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, + }, + ]); + fn.onCall(1).resolves([ + { + actor_wallet_id: wallet2.getId(), + target_wallet_id: subWallet.getId(), + request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, + }, + ]); + const list = await wallet.getTrustRelationshipsRequestedToMe(); expect(list).lengthOf(2); }); }); - describe("checkManageRecycle", () => { - + describe('checkManageRecycle', () => { const walletA = new Wallet(uuid.v4()); - const walletB = new Wallet(uuid.v4()) - const trustIdA = uuid.v4() - const trustIdB = uuid.v4() + const walletB = new Wallet(uuid.v4()); + const trustIdA = uuid.v4(); + const trustIdB = uuid.v4(); - it("A manage B, now B request to manage A, should throw error", async () => { + it('A manage B, now B request to manage A, should throw error', async () => { const trustRelationshipTrusted = { id: trustIdA, type: TrustRelationship.ENTITY_TRUST_TYPE.manage, request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.manage, actor_wallet_id: walletA.getId(), target_wallet_id: walletB.getId(), - } + }; const trustRelationshipRequested = { id: trustIdB, type: TrustRelationship.ENTITY_TRUST_TYPE.manage, request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.manage, actor_wallet_id: walletB.getId(), target_wallet_id: walletA.getId(), - } - sinon.stub(Wallet.prototype, "getTrustRelationshipsTrusted").resolves([trustRelationshipTrusted]); + }; + sinon + .stub(Wallet.prototype, 'getTrustRelationshipsTrusted') + .resolves([trustRelationshipTrusted]); await jestExpect(async () => { await walletA.checkManageCircle(trustRelationshipRequested); }).rejects.toThrow(/circle/); }); - it("A manage B, now A request to yield B, should throw error", async () => { + it('A manage B, now A request to yield B, should throw error', async () => { const trustRelationshipTrusted = { id: trustIdA, type: TrustRelationship.ENTITY_TRUST_TYPE.manage, request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.manage, actor_wallet_id: walletA.getId(), target_wallet_id: walletB.getId(), - } + }; const trustRelationshipRequested = { id: trustIdB, type: TrustRelationship.ENTITY_TRUST_TYPE.manage, request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.yield, actor_wallet_id: walletA.getId(), target_wallet_id: walletB.getId(), - } - sinon.stub(Wallet.prototype, "getTrustRelationshipsTrusted").resolves([trustRelationshipTrusted]); + }; + sinon + .stub(Wallet.prototype, 'getTrustRelationshipsTrusted') + .resolves([trustRelationshipTrusted]); await jestExpect(async () => { await walletA.checkManageCircle(trustRelationshipRequested); }).rejects.toThrow(/circle/); }); - it("A yield B, now B request to yield A, should throw error", async () => { + it('A yield B, now B request to yield A, should throw error', async () => { const trustRelationshipTrusted = { id: trustIdA, type: TrustRelationship.ENTITY_TRUST_TYPE.manage, request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.yield, actor_wallet_id: walletA.getId(), target_wallet_id: walletB.getId(), - } + }; const trustRelationshipRequested = { id: trustIdB, type: TrustRelationship.ENTITY_TRUST_TYPE.manage, request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.yield, actor_wallet_id: walletB.getId(), target_wallet_id: walletA.getId(), - } - sinon.stub(Wallet.prototype, "getTrustRelationshipsTrusted").resolves([trustRelationshipTrusted]); + }; + sinon + .stub(Wallet.prototype, 'getTrustRelationshipsTrusted') + .resolves([trustRelationshipTrusted]); await jestExpect(async () => { await walletA.checkManageCircle(trustRelationshipRequested); }).rejects.toThrow(/circle/); }); - it("A yield B, now A request to manage B, should throw error", async () => { + it('A yield B, now A request to manage B, should throw error', async () => { const trustRelationshipTrusted = { id: trustIdA, type: TrustRelationship.ENTITY_TRUST_TYPE.manage, request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.yield, actor_wallet_id: walletA.getId(), target_wallet_id: walletB.getId(), - } + }; const trustRelationshipRequested = { id: trustIdB, type: TrustRelationship.ENTITY_TRUST_TYPE.manage, request_type: TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.manage, actor_wallet_id: walletA.getId(), target_wallet_id: walletB.getId(), - } - sinon.stub(Wallet.prototype, "getTrustRelationshipsTrusted").resolves([trustRelationshipTrusted]); + }; + sinon + .stub(Wallet.prototype, 'getTrustRelationshipsTrusted') + .resolves([trustRelationshipTrusted]); await jestExpect(async () => { await walletA.checkManageCircle(trustRelationshipRequested); }).rejects.toThrow(/circle/); }); }); - describe("checkDuplicateRequest", () => { - + describe('checkDuplicateRequest', () => { const walletA = new Wallet(uuid.v4()); - const walletB = new Wallet(uuid.v4()) - const trustIdA = uuid.v4() - const trustIdB = uuid.v4() + const walletB = new Wallet(uuid.v4()); + const trustIdA = uuid.v4(); + const trustIdB = uuid.v4(); - it("A send B trust has been requested, now request again, should throw error", async () => { + it('A send B trust has been requested, now request again, should throw error', async () => { const trustRelationshipRequested = { id: trustIdA, type: TrustRelationship.ENTITY_TRUST_TYPE.send, @@ -1284,7 +1429,7 @@ describe("Wallet", () => { actor_wallet_id: walletA.getId(), target_wallet_id: walletB.getId(), state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.requested, - } + }; const trustRelationshipRequesting = { id: trustIdB, type: TrustRelationship.ENTITY_TRUST_TYPE.send, @@ -1292,22 +1437,24 @@ describe("Wallet", () => { actor_wallet_id: walletA.getId(), target_wallet_id: walletB.getId(), state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.requested, - } - sinon.stub(Wallet.prototype, "getTrustRelationships").resolves([trustRelationshipRequested]); + }; + sinon + .stub(Wallet.prototype, 'getTrustRelationships') + .resolves([trustRelationshipRequested]); await jestExpect(async () => { await wallet.checkDuplicateRequest(trustRelationshipRequesting); }).rejects.toThrow(/has been/); }); - it("A send B trust has been trusted, now request B receive A, should throw error", async () => { + it('A send B trust has been trusted, now request B receive A, should throw error', async () => { const trustRelationshipRequested = { - id: trustIdA, + id: trustIdA, type: TrustRelationship.ENTITY_TRUST_TYPE.send, request_type: TrustRelationship.ENTITY_TRUST_TYPE.send, actor_wallet_id: walletA.getId(), target_wallet_id: walletB.getId(), state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, - } + }; const trustRelationshipRequesting = { id: trustIdB, type: TrustRelationship.ENTITY_TRUST_TYPE.send, @@ -1315,14 +1462,16 @@ describe("Wallet", () => { actor_wallet_id: walletB.getId(), target_wallet_id: walletA.getId(), state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.requested, - } - sinon.stub(Wallet.prototype, "getTrustRelationships").resolves([trustRelationshipRequested]); + }; + sinon + .stub(Wallet.prototype, 'getTrustRelationships') + .resolves([trustRelationshipRequested]); await jestExpect(async () => { await wallet.checkDuplicateRequest(trustRelationshipRequesting); }).rejects.toThrow(/has been/); }); - it("A manage B trust has been requested, now request B yield A, should throw error", async () => { + it('A manage B trust has been requested, now request B yield A, should throw error', async () => { const trustRelationshipRequested = { id: trustIdA, type: TrustRelationship.ENTITY_TRUST_TYPE.manage, @@ -1330,7 +1479,7 @@ describe("Wallet", () => { actor_wallet_id: walletA.getId(), target_wallet_id: walletB.getId(), state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.requested, - } + }; const trustRelationshipRequesting = { id: trustIdB, type: TrustRelationship.ENTITY_TRUST_TYPE.manage, @@ -1338,64 +1487,67 @@ describe("Wallet", () => { actor_wallet_id: walletB.getId(), target_wallet_id: walletA.getId(), state: TrustRelationship.ENTITY_TRUST_STATE_TYPE.requested, - } - sinon.stub(Wallet.prototype, "getTrustRelationships").resolves([trustRelationshipRequested]); + }; + sinon + .stub(Wallet.prototype, 'getTrustRelationships') + .resolves([trustRelationshipRequested]); await jestExpect(async () => { await wallet.checkDuplicateRequest(trustRelationshipRequesting); }).rejects.toThrow(/has been/); }); }); - describe("getTransferById", () => { + describe('getTransferById', () => { + const transferId = uuid.v4(); - const transferId = uuid.v4() - - it("Successfully", async () => { - sinon.stub(Wallet.prototype, "getTransfers").resolves([{ - id: transferId , - }]); + it('Successfully', async () => { + sinon.stub(Wallet.prototype, 'getTransfers').resolves([ + { + id: transferId, + }, + ]); const transfer = await wallet.getTransferById(transferId); - expect(transfer).property("id").eq(transferId); + expect(transfer).property('id').eq(transferId); }); - it("Not fond", async () => { - sinon.stub(Wallet.prototype, "getTransfers").resolves([]); + it('Not fond', async () => { + sinon.stub(Wallet.prototype, 'getTransfers').resolves([]); await jestExpect(async () => { await wallet.getTransferById(1); }).rejects.toThrow(/not find/); }); }); - describe("getTokensByTransferId", () => { + describe('getTokensByTransferId', () => { + const token = new Token(uuid.v4()); + const transferId = uuid.v4(); - const token = new Token(uuid.v4()) - const transferId = uuid.v4() - - it("Completed transfer", async () => { - const transfer = { + it('Completed transfer', async () => { + const transfer = { id: transferId, state: Transfer.STATE.completed, }; - sinon.stub(Wallet.prototype, "getTransferById").resolves(transfer); - const fn = sinon.stub(TokenService.prototype, "getTokensByTransferId").resolves([token]); + sinon.stub(Wallet.prototype, 'getTransferById').resolves(transfer); + const fn = sinon + .stub(TokenService.prototype, 'getTokensByTransferId') + .resolves([token]); const tokens = await wallet.getTokensByTransferId(transferId); expect(tokens).lengthOf(1); expect(fn).calledWith(transferId); }); - it("Pending/requested transfer", async () => { - const transfer = { + it('Pending/requested transfer', async () => { + const transfer = { id: transferId, state: Transfer.STATE.pending, }; - sinon.stub(Wallet.prototype, "getTransferById").resolves(transfer); - const fn = sinon.stub(TokenService.prototype, "getTokensByPendingTransferId").resolves([token]); + sinon.stub(Wallet.prototype, 'getTransferById').resolves(transfer); + const fn = sinon + .stub(TokenService.prototype, 'getTokensByPendingTransferId') + .resolves([token]); const tokens = await wallet.getTokensByTransferId(transferId); expect(tokens).lengthOf(1); expect(fn).calledWith(transferId); }); - }); - - }); diff --git a/server/repositories/ApiKeyRepository.js b/server/repositories/ApiKeyRepository.js index 61146f3d..5174123a 100644 --- a/server/repositories/ApiKeyRepository.js +++ b/server/repositories/ApiKeyRepository.js @@ -1,5 +1,5 @@ -const HttpError = require("../utils/HttpError"); const expect = require("expect-runtime"); +const HttpError = require("../utils/HttpError"); const Session = require("../models/Session"); diff --git a/server/repositories/ApiKeyRepository.spec.js b/server/repositories/ApiKeyRepository.spec.js index 41711e7f..7a3a3014 100644 --- a/server/repositories/ApiKeyRepository.spec.js +++ b/server/repositories/ApiKeyRepository.spec.js @@ -1,6 +1,7 @@ const {expect} = require("chai"); -const knex = require("../database/knex"); const mockKnex = require("mock-knex"); +const knex = require("../database/knex"); + const tracker = mockKnex.getTracker(); const ApiKeyRepository = require("./ApiKeyRepository"); const Session = require("../models/Session"); diff --git a/server/repositories/BaseRepository.js b/server/repositories/BaseRepository.js index 074682d2..6bef117c 100644 --- a/server/repositories/BaseRepository.js +++ b/server/repositories/BaseRepository.js @@ -1,7 +1,7 @@ -const Session = require("../models/Session"); const expect = require("expect-runtime"); -const HttpError = require("../utils/HttpError"); const log = require("loglevel"); +const Session = require("../models/Session"); +const HttpError = require("../utils/HttpError"); class BaseRepository{ @@ -26,24 +26,25 @@ class BaseRepository{ * limit: number */ async getByFilter(filter, options){ + const offset = options && options.offset ? options.offset : 0 const whereBuilder = function(object, builder){ let result = builder; - if(object['and']){ + if(object.and){ expect(Object.keys(object)).lengthOf(1); - expect(object['and']).a(expect.any(Array)); - for(let one of object['and']){ - if(one['or']){ + expect(object.and).a(expect.any(Array)); + for(const one of object.and){ + if(one.or){ result = result.andWhere(subBuilder => whereBuilder(one, subBuilder)); }else{ expect(Object.keys(one)).lengthOf(1); result = result.andWhere(Object.keys(one)[0], Object.values(one)[0]); } } - }else if(object['or']){ + }else if(object.or){ expect(Object.keys(object)).lengthOf(1); - expect(object['or']).a(expect.any(Array)); - for(let one of object['or']){ - if(one['and']){ + expect(object.or).a(expect.any(Array)); + for(const one of object.or){ + if(one.and){ result = result.orWhere(subBuilder => whereBuilder(one, subBuilder)); }else{ expect(Object.keys(one)).lengthOf(1); @@ -55,9 +56,9 @@ class BaseRepository{ } return result; } - let promise = this._session.getDB().select().table(this._tableName).where(builder => whereBuilder(filter, builder)); + let promise = this._session.getDB().select().table(this._tableName).offset(offset).where(builder => whereBuilder(filter, builder)); if(options && options.limit){ - promise = promise.limit(options && options.limit); + promise = promise.limit(options.limit); } const result = await promise; expect(result).a(expect.any(Array)); @@ -73,9 +74,9 @@ class BaseRepository{ } async update(object){ - let objectCopy = {} + const objectCopy = {} Object.assign(objectCopy, object) - const id = object.id + const {id} = object delete objectCopy.id const result = await this._session.getDB()(this._tableName).update(objectCopy).where("id", id).returning("*"); return result[0]; @@ -85,7 +86,7 @@ class BaseRepository{ * update all rows matching given id */ async updateByIds(object, ids){ - let objectCopy = {} + const objectCopy = {} Object.assign(objectCopy, object) delete objectCopy.id const result = await this._session.getDB()(this._tableName).update(objectCopy).whereIn("id", ids); @@ -93,9 +94,6 @@ class BaseRepository{ async create(object){ const result = await this._session.getDB()(this._tableName).insert(object).returning("*"); - expect(result).match([{ - id: expect.anything(), - }]); return result[0]; } diff --git a/server/repositories/BaseRepository.spec.js b/server/repositories/BaseRepository.spec.js index 713a53fe..4f814249 100644 --- a/server/repositories/BaseRepository.spec.js +++ b/server/repositories/BaseRepository.spec.js @@ -2,8 +2,10 @@ const BaseRepository = require("./BaseRepository"); const {expect} = require("chai"); const knex = require("../database/knex"); const mockKnex = require("mock-knex"); + const tracker = mockKnex.getTracker(); const jestExpect = require("expect"); +const uuid = require('uuid'); const Session = require("../models/Session"); describe("BaseRepository", () => { @@ -32,11 +34,11 @@ describe("BaseRepository", () => { expect(entity).property("id").eq(1); }); - //TODO + // TODO it.skip("getById can not find result, should throw 404", () => { }); - describe.only("getByFilter", () => { + describe("getByFilter", () => { it("getByFilter", async () => { tracker.uninstall(); @@ -68,6 +70,22 @@ describe("BaseRepository", () => { expect(result[0]).property("id").eq(1); }); + it("getByFilter with offset", async () => { + tracker.uninstall(); + tracker.install(); + tracker.on("query", (query) => { + expect(query.sql).match(/select.*testTable.*offset.*/); + query.response([{id:2}]); + }); + const result = await baseRepository.getByFilter({ + name: "testName", + },{ + offset: 1, + }); + expect(result).lengthOf(1); + expect(result[0]).property("id").eq(2); + }); + describe("'and' 'or' phrase", () => { it("{and: [{c:1}, {b:2}]}", async () => { @@ -195,10 +213,9 @@ describe("BaseRepository", () => { query.response({id:1}); }); const result = await baseRepository.update({ - id: 1, + id: uuid.v4(), name: "testName", }); - expect(result).property("id").eq(1); }); }); @@ -235,7 +252,7 @@ describe("BaseRepository", () => { expect(result).eq(1); }); - //TODO + // TODO describe.skip("count support and and or", () => { }); }); diff --git a/server/repositories/TokenRepository.js b/server/repositories/TokenRepository.js index 569fe5a9..62c9500b 100644 --- a/server/repositories/TokenRepository.js +++ b/server/repositories/TokenRepository.js @@ -1,21 +1,26 @@ +const expect = require('expect-runtime'); const knex = require('../database/knex'); const config = require('../../config/config'); -const HttpError = require("../utils/HttpError"); -const BaseRepository = require("./BaseRepository"); -const expect = require("expect-runtime"); -const Session = require("../models/Session"); +const HttpError = require('../utils/HttpError'); +const BaseRepository = require('./BaseRepository'); +const Session = require('../models/Session'); -class TokenRepository extends BaseRepository{ - constructor(session){ - super("token", session); - this._tableName = "token"; +class TokenRepository extends BaseRepository { + constructor(session) { + super('token', session); + this._tableName = 'token'; this._session = session; } - async getById(id){ - const result = await this._session.getDB()(this._tableName).where("id", id) + async getById(id) { + const result = await this._session + .getDB()(this._tableName) + .where('id', id) .first(); - expect(result,() => new HttpError(404, `can not found token by id:${id}`)).match({ + expect( + result, + () => new HttpError(404, `can not found token by id:${id}`), + ).match({ id: expect.any(String), }); return result; @@ -24,16 +29,15 @@ class TokenRepository extends BaseRepository{ /* * select transaction table by transfer id, return matched tokens */ - async getByTransferId(transferId){ - const result = await this._session.getDB().raw(` + async getByTransferId(transferId, limit, offset = 0) { + return await this._session.getDB().raw(` SELECT "token".* FROM "token" JOIN "transaction" ON "token".id = "transaction".token_id - WHERE "transaction".transfer_id = '226f76cd-52b0-486b-b58a-98230696c748' - `); - return result; + WHERE "transaction".transfer_id = ${transferId} + LIMIT ${limit} + OFFSET ${offset}`); } - } module.exports = TokenRepository; diff --git a/server/repositories/TokenRepository.spec.js b/server/repositories/TokenRepository.spec.js index 8c65fb16..21a5dca9 100644 --- a/server/repositories/TokenRepository.spec.js +++ b/server/repositories/TokenRepository.spec.js @@ -1,8 +1,9 @@ -const knex = require("../database/knex"); -const TokenRepository = require("./TokenRepository"); const sinon = require("sinon"); const {expect} = require("chai"); const mockKnex = require("mock-knex"); +const TokenRepository = require("./TokenRepository"); +const knex = require("../database/knex"); + const tracker = mockKnex.getTracker(); const Session = require("../models/Session"); @@ -20,21 +21,13 @@ describe("TokenRepository", () => { mockKnex.unmock(knex); }); - it("get by uuid successfully", async () => { - tracker.on("query", (query) => { - expect(query.sql).match(/select.*uuid.*/); - query.response({id:1, token: "testUuid"}); - }); - const token = await tokenRepository.getByUUID("testUuid"); - expect(token).property("token").eq("testUuid"); - }); it("getByTransferId", async () => { tracker.on("query", (query) => { expect(query.sql).match(/select.*token.*transaction.*transfer_id/is); query.response([{id:1, token: "testUuid"}]); }); - const tokens = await tokenRepository.getByTransferId("testUuid"); + const tokens = await tokenRepository.getByTransferId('226f76cd-52b0-486b-b58a-98230696c748'); expect(tokens).lengthOf(1); }); diff --git a/server/repositories/TransactionRepository.js b/server/repositories/TransactionRepository.js index 1d72a4b5..45cec3ef 100644 --- a/server/repositories/TransactionRepository.js +++ b/server/repositories/TransactionRepository.js @@ -1,9 +1,8 @@ -const BaseRepository = require("./BaseRepository"); -const expect = require("expect-runtime"); +const BaseRepository = require('./BaseRepository'); -class TransferRepository extends BaseRepository{ - constructor(session){ - super("transaction", session); +class TransferRepository extends BaseRepository { + constructor(session) { + super('transaction', session); this._session = session; } } diff --git a/server/repositories/TransactionRepository.spec.js b/server/repositories/TransactionRepository.spec.js index 1d3d6657..61fa71b3 100644 --- a/server/repositories/TransactionRepository.spec.js +++ b/server/repositories/TransactionRepository.spec.js @@ -2,6 +2,7 @@ const TransactionRepository = require("./TransactionRepository"); const {expect} = require("chai"); const knex = require("../database/knex"); const mockKnex = require("mock-knex"); + const tracker = mockKnex.getTracker(); const jestExpect = require("expect"); const Session = require("../models/Session"); diff --git a/server/repositories/TransferRepository.js b/server/repositories/TransferRepository.js index e2c91dcf..a4a89f30 100644 --- a/server/repositories/TransferRepository.js +++ b/server/repositories/TransferRepository.js @@ -1,7 +1,7 @@ +const expect = require("expect-runtime"); const knex = require("../database/knex"); const Transfer = require("../models/Transfer"); const BaseRepository = require("./BaseRepository"); -const expect = require("expect-runtime"); const Session = require("../models/Session"); class TransferRepository extends BaseRepository{ @@ -17,7 +17,7 @@ class TransferRepository extends BaseRepository{ object.active = true; const result = await super.create(object); expect(result).match({ - id: expect.any(String), + id: expect.anything(), }); return result; } diff --git a/server/repositories/TransferRepository.spec.js b/server/repositories/TransferRepository.spec.js index 176f5fb6..b3cc4b24 100644 --- a/server/repositories/TransferRepository.spec.js +++ b/server/repositories/TransferRepository.spec.js @@ -1,7 +1,8 @@ -const TransferRepository = require("./TransferRepository"); const {expect} = require("chai"); -const knex = require("../database/knex"); const mockKnex = require("mock-knex"); +const TransferRepository = require("./TransferRepository"); +const knex = require("../database/knex"); + const tracker = mockKnex.getTracker(); const Session = require("../models/Session"); const uuid = require('uuid'); @@ -50,12 +51,12 @@ describe("TransferRepository", () => { [ function firstQuery() { expect(query.sql).match(/select.*transfer.*/); - query.response({id:1}); + query.response({id:uuid.v4()}); }, ][step - 1](); }); const result = await transferRepository.getById(1); - expect(result).property("id").eq(1); + expect(result).property("id").a("string"); }); it("getPendingTransfers", async () => { diff --git a/server/repositories/TrustRepository.js b/server/repositories/TrustRepository.js index 4c165dc4..5ee4f008 100644 --- a/server/repositories/TrustRepository.js +++ b/server/repositories/TrustRepository.js @@ -1,47 +1,50 @@ -const HttpError = require("../utils/HttpError"); -const BaseRepository = require("./BaseRepository"); -const expect = require("expect-runtime"); -const Session = require("../models/Session"); - -class TrustRepository extends BaseRepository{ - constructor(session){ - super("wallet_trust", session); - this._tableName = "wallet_trust"; +const HttpError = require('../utils/HttpError'); +const BaseRepository = require('./BaseRepository'); +const Session = require('../models/Session'); + +class TrustRepository extends BaseRepository { + constructor(session) { + super('wallet_trust', session); + this._tableName = 'wallet_trust'; this._session = session; } - async get(){ - //const trust_relationship_instance = new trust_relationship(1); - const list = await this._session.getDB().select() - .table(this._tableName); + async get() { + // const trust_relationship_instance = new trust_relationship(1); + const list = await this._session.getDB().select().table(this._tableName); return list; } - async getByOriginatorId(id){ - const list = await this._session.getDB().select() + async getByOriginatorId(id) { + const list = await this._session + .getDB() + .select() .table(this._tableName) - .where("originator_wallet_id", id); + .where('originator_wallet_id', id); return list; } - async getByTargetId(id){ - const list = await this._session.getDB().select() + async getByTargetId(id) { + const list = await this._session + .getDB() + .select() .table(this._tableName) - .where("target_wallet_id", id); + .where('target_wallet_id', id); return list; } - async getTrustedByOriginatorId(id){ - const list = await this._session.getDB().select() + async getTrustedByOriginatorId(id) { + const list = await this._session + .getDB() + .select() .table(this._tableName) .where({ originator_wallet_id: id, - state: require("../models/TrustRelationship").ENTITY_TRUST_STATE_TYPE.trusted, + state: require('../models/TrustRelationship').ENTITY_TRUST_STATE_TYPE + .trusted, }); return list; } - } - module.exports = TrustRepository; diff --git a/server/repositories/TrustRepository.spec.js b/server/repositories/TrustRepository.spec.js index bbba919e..45b52554 100644 --- a/server/repositories/TrustRepository.spec.js +++ b/server/repositories/TrustRepository.spec.js @@ -1,9 +1,11 @@ -const TrustRepository = require("./TrustRepository"); const {expect} = require("chai"); -const knex = require("../database/knex"); const mockKnex = require("mock-knex"); +const TrustRepository = require("./TrustRepository"); +const knex = require("../database/knex"); + const tracker = mockKnex.getTracker(); const Session = require("../models/Session"); +const uuid = require('uuid'); describe("TrustRepository", () => { @@ -46,8 +48,7 @@ describe("TrustRepository", () => { } ][step - 1](); }); - const result = await trustRepository.create({}); - expect(result).property('id').a('number'); + await trustRepository.create({id:uuid.v4(),state: "ok"}); }); it("getById", async () => { @@ -67,7 +68,10 @@ describe("TrustRepository", () => { expect(query.sql).match(/update.*trust.*/); query.response([{}]); }); - await trustRepository.update({id:1}); + await trustRepository.update({ + id:uuid.v4(), + actor_wallet_id: uuid.v4(), + }); }); }); diff --git a/server/repositories/WalletRepository.js b/server/repositories/WalletRepository.js index 883ea4db..629daf2f 100644 --- a/server/repositories/WalletRepository.js +++ b/server/repositories/WalletRepository.js @@ -1,8 +1,8 @@ /* * The model for: entity, wallet, entity table and so on */ -const HttpError = require("../utils/HttpError"); const expect = require("expect-runtime"); +const HttpError = require("../utils/HttpError"); const BaseRepository = require("./BaseRepository"); const Session = require("../models/Session"); diff --git a/server/repositories/WalletRepository.spec.js b/server/repositories/WalletRepository.spec.js index 98020395..697a1e93 100644 --- a/server/repositories/WalletRepository.spec.js +++ b/server/repositories/WalletRepository.spec.js @@ -2,6 +2,7 @@ const WalletRepository = require("./WalletRepository"); const {expect} = require("chai"); const knex = require("../database/knex"); const mockKnex = require("mock-knex"); + const tracker = mockKnex.getTracker(); const jestExpect = require("expect"); const Session = require("../models/Session"); diff --git a/server/routes/authRouter.js b/server/routes/authRouter.js index 83455985..809d64ae 100644 --- a/server/routes/authRouter.js +++ b/server/routes/authRouter.js @@ -1,10 +1,11 @@ const express = require("express"); + const authRouter = express.Router(); +const Joi = require("joi"); const helper = require("./utils"); const Wallet = require("../models/Wallet"); const WalletService = require("../services/WalletService"); const JWTService = require("../services/JWTService"); -const Joi = require("joi"); const Session = require("../models/Session"); authRouter.post( diff --git a/server/routes/authRouter.spec.js b/server/routes/authRouter.spec.js index 71dd7b69..b6988ac5 100644 --- a/server/routes/authRouter.spec.js +++ b/server/routes/authRouter.spec.js @@ -1,11 +1,11 @@ const request = require("supertest"); const express = require("express"); -const authRouter = require("./authRouter"); const {expect} = require("chai"); -const {errorHandler} = require("./utils"); const sinon = require("sinon"); -const ApiKeyService = require("../services/ApiKeyService"); const bodyParser = require('body-parser'); +const authRouter = require("./authRouter"); +const {errorHandler} = require("./utils"); +const ApiKeyService = require("../services/ApiKeyService"); const WalletService = require("../services/WalletService"); const JWTService = require("../services/JWTService"); diff --git a/server/routes/tokenRouter.js b/server/routes/tokenRouter.js index 9bbc1fbb..64f0073f 100644 --- a/server/routes/tokenRouter.js +++ b/server/routes/tokenRouter.js @@ -1,11 +1,11 @@ const express = require('express'); const { check, validationResult } = require('express-validator'); +const Joi = require("joi"); const helper = require("./utils"); const TokenService = require("../services/TokenService"); const WalletService = require("../services/WalletService"); const HttpError = require("../utils/HttpError"); const Session = require("../models/Session"); -const Joi = require("joi"); const tokenRouter = express.Router(); @@ -19,14 +19,14 @@ tokenRouter.get('/:id', const tokenService = new TokenService(session); const walletService = new WalletService(session); const token = await tokenService.getById(id); - //check permission + // check permission const json = await token.toJSON(); const walletLogin = await walletService.getById(res.locals.wallet_id); let walletIds = [walletLogin.getId()]; const subWallets = await walletLogin.getSubWallets(); walletIds = [...walletIds, ...subWallets.map(e => e.getId())]; if(walletIds.includes(json.wallet_id)){ - //pass + // pass }else{ throw new HttpError(401, "Have no permission to visit this token"); } @@ -42,30 +42,29 @@ tokenRouter.get('/', Joi.assert( req.query, Joi.object({ - limit: Joi.number().min(0).max(1000).required(), - start: Joi.number().min(1).max(10000).integer(), + limit: Joi.number().min(1).max(1000).required().default(1000), + offset: Joi.number().min(0).integer().default(0), wallet: Joi.string(), }) ); - const {limit, wallet, start} = req.query; + const {limit, wallet, offset} = req.query; const session = new Session(); const tokenService = new TokenService(session); const walletService = new WalletService(session); const walletLogin = await walletService.getById(res.locals.wallet_id); let tokens = []; + if(wallet){ const walletInstance = await walletService.getByName(wallet); const isSub = await walletLogin.hasControlOver(walletInstance); if(!isSub){ - throw new HttpError(403, "Wallet do not belongs to wallet logged in"); + throw new HttpError(403, "Wallet does not belong to wallet logged in"); } - tokens = await tokenService.getByOwner(walletInstance); + tokens = await tokenService.getByOwner(walletInstance, limit, offset); }else{ - tokens = await tokenService.getByOwner(walletLogin); + tokens = await tokenService.getByOwner(walletLogin, limit, offset); } - //filter tokens by query, TODO optimization required - tokens = tokens.slice(start? start-1:0, limit); const tokensJson = []; for(const token of tokens){ const json = await token.toJSON(); @@ -85,46 +84,38 @@ tokenRouter.get('/:id/transactions', Joi.assert( req.query, Joi.object({ - limit: Joi.number().min(0).max(1000).required(), - start: Joi.number().min(1).max(10000).integer(), + limit: Joi.number().min(1).max(1000).integer().default(1000).required(), + offset: Joi.number().min(0).integer(), id: Joi.string().guid(), transactions: Joi.string(), }) ); - const {limit, start} = req.query; + const {limit, offset} = req.query; const session = new Session(); const {id} = req.params; const tokenService = new TokenService(session); const walletService = new WalletService(session); const token = await tokenService.getById(id); - //check permission + // check permission const json = await token.toJSON(); const walletLogin = await walletService.getById(res.locals.wallet_id); let walletIds = [walletLogin.getId()]; const subWallets = await walletLogin.getSubWallets(); walletIds = [...walletIds, ...subWallets.map(e => e.getId())]; if(walletIds.includes(json.wallet_id)){ - //pass + // pass }else{ throw new HttpError(401, "Have no permission to visit this token"); } - const transactions = await token.getTransactions(); - let response = []; + const transactions = await token.getTransactions(limit, offset); + + const response = []; for(const t of transactions){ const transaction = await tokenService.convertToResponse(t); response.push(transaction); } - //filter transaction json by query - let numStart = parseInt(start); - let numLimit = parseInt(limit); - let numBegin = numStart?numStart-1:0; - let numEnd=numBegin+numLimit; - response = response.slice(numBegin, numEnd); - // console.log(numBegin); - // console.log(numEnd); - // console.log(response); res.status(200).json({ history: response, }); diff --git a/server/routes/tokenRouter.spec.js b/server/routes/tokenRouter.spec.js index 19138f37..28d6a3ad 100644 --- a/server/routes/tokenRouter.spec.js +++ b/server/routes/tokenRouter.spec.js @@ -1,30 +1,30 @@ -const request = require("supertest"); -const express = require("express"); -const tokenRouter = require("./tokenRouter"); -const {expect} = require("chai"); -const {errorHandler} = require("./utils"); -const sinon = require("sinon"); -const ApiKeyService = require("../services/ApiKeyService"); +const request = require('supertest'); +const express = require('express'); +const { expect } = require('chai'); +const sinon = require('sinon'); const bodyParser = require('body-parser'); -const WalletService = require("../services/WalletService"); -const JWTService = require("../services/JWTService"); -const HttpError = require("../utils/HttpError"); -const Token = require("../models/Token"); -const TokenService = require("../services/TokenService"); -const Wallet = require("../models/Wallet"); -const Transfer = require("../models/Transfer"); -const TransferService = require("../services/TransferService"); const uuid = require('uuid'); - -describe("tokenRouter", () => { +const tokenRouter = require('./tokenRouter'); +const { errorHandler } = require('./utils'); +const ApiKeyService = require('../services/ApiKeyService'); +const WalletService = require('../services/WalletService'); +const JWTService = require('../services/JWTService'); +const HttpError = require('../utils/HttpError'); +const Token = require('../models/Token'); +const TokenService = require('../services/TokenService'); +const Wallet = require('../models/Wallet'); +const Transfer = require('../models/Transfer'); +const TransferService = require('../services/TransferService'); + +describe('tokenRouter', () => { let app; const authenticatedWallet = { - id: uuid.v4() - } + id: uuid.v4(), + }; beforeEach(() => { - sinon.stub(ApiKeyService.prototype, "check"); - sinon.stub(JWTService.prototype, "verify").returns({ + sinon.stub(ApiKeyService.prototype, 'check'); + sinon.stub(JWTService.prototype, 'verify').returns({ id: authenticatedWallet.id, }); app = express(); @@ -32,190 +32,207 @@ describe("tokenRouter", () => { app.use(bodyParser.json()); // parse application/json app.use(tokenRouter); app.use(errorHandler); - }) + }); afterEach(() => { sinon.restore(); - }) + }); - describe("get tokens, GET /", () => { - const tokenId = uuid.v4() - const token2Id = uuid.v4() - const walletId = uuid.v4() - const wallet2Id = uuid.v4() - const transactionId = uuid.v4() - const captureId = uuid.v4() - const capture2Id = uuid.v4() + describe('get tokens, GET /', () => { + const tokenId = uuid.v4(); + const token2Id = uuid.v4(); + const walletId = uuid.v4(); + const wallet2Id = uuid.v4(); + const transactionId = uuid.v4(); + const captureId = uuid.v4(); + const capture2Id = uuid.v4(); const token = new Token({ id: tokenId, wallet_id: walletId, - capture_id: captureId + capture_id: captureId, }); const token2 = new Token({ id: token2Id, wallet_id: wallet2Id, - capture_id: capture2Id + capture_id: capture2Id, }); const wallet = new Wallet(walletId); const wallet2 = new Wallet(wallet2Id); - - it("limit parameters missed", async () => { - const res = await request(app) - .get("/"); - expect(res).property("statusCode").eq(422); + it('limit parameters missed', async () => { + const res = await request(app).get('/'); + expect(res).property('statusCode').eq(422); }); - it("successfully, default wallet", async () => { - sinon.stub(TokenService.prototype, "getByOwner").resolves([token, token2]); - sinon.stub(WalletService.prototype, "getById").resolves(wallet); - const res = await request(app) - .get("/?limit=10&start=2"); - expect(res).property("statusCode").eq(200); + it('successfully, default wallet', async () => { + sinon.stub(TokenService.prototype, 'getByOwner').resolves([token2]); + sinon.stub(WalletService.prototype, 'getById').resolves(wallet); + const res = await request(app).get('/?limit=10&offset=1'); + expect(res).property('statusCode').eq(200); expect(res.body.tokens).lengthOf(1); - expect(res.body.tokens[0]).property("id").eq(token2Id); - expect(res.body.tokens[0]).property("links").property("capture").eq("/webmap/tree?uuid=" + capture2Id); + expect(res.body.tokens[0]).property('id').eq(token2Id); + expect(res.body.tokens[0]) + .property('links') + .property('capture') + .eq(`/webmap/tree?uuid=${capture2Id}`); }); - it("successfully, sub wallet", async () => { - sinon.stub(TokenService.prototype, "getByOwner").resolves([token]); - sinon.stub(WalletService.prototype, "getById").resolves(wallet); - sinon.stub(WalletService.prototype, "getByName").resolves(wallet2); - sinon.stub(Wallet.prototype, "hasControlOver").resolves(true); - const res = await request(app) - .get(`/?limit=10&wallet=${wallet2Id}`); - expect(res).property("statusCode").eq(200); - expect(res.body.tokens[0]).property("id").eq(tokenId); - expect(res.body.tokens[0]).property("links").property("capture").eq("/webmap/tree?uuid=" + captureId); + it('successfully, sub wallet', async () => { + sinon.stub(TokenService.prototype, 'getByOwner').resolves([token]); + sinon.stub(WalletService.prototype, 'getById').resolves(wallet); + sinon.stub(WalletService.prototype, 'getByName').resolves(wallet2); + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(true); + const res = await request(app).get(`/?limit=10&wallet=${wallet2Id}`); + expect(res).property('statusCode').eq(200); + expect(res.body.tokens[0]).property('id').eq(tokenId); + expect(res.body.tokens[0]) + .property('links') + .property('capture') + .eq(`/webmap/tree?uuid=${captureId}`); }); - it("sub wallet, no permission", async () => { - sinon.stub(TokenService.prototype, "getByOwner").resolves([token]); - sinon.stub(WalletService.prototype, "getById").resolves(wallet); - sinon.stub(WalletService.prototype, "getByName").resolves(wallet2); - sinon.stub(Wallet.prototype, "hasControlOver").resolves(false); - const res = await request(app) - .get("/?limit=10&wallet=B"); - expect(res).property("statusCode").eq(403); + it('sub wallet, no permission', async () => { + sinon.stub(TokenService.prototype, 'getByOwner').resolves([token]); + sinon.stub(WalletService.prototype, 'getById').resolves(wallet); + sinon.stub(WalletService.prototype, 'getByName').resolves(wallet2); + sinon.stub(Wallet.prototype, 'hasControlOver').resolves(false); + const res = await request(app).get('/?limit=10&wallet=B'); + expect(res).property('statusCode').eq(403); }); }); - - describe("get token, GET /:token_id/transactions", () => { - - const tokenId = uuid.v4() - const token2Id = uuid.v4() - const walletId = uuid.v4() - const wallet2Id = uuid.v4() - const transactionId = uuid.v4() - const captureId = uuid.v4() - const capture2Id = uuid.v4() + describe('get token, GET /:token_id/transactions', () => { + const tokenId = uuid.v4(); + const token2Id = uuid.v4(); + const walletId = uuid.v4(); + const wallet2Id = uuid.v4(); + const transactionId = uuid.v4(); + const captureId = uuid.v4(); + const capture2Id = uuid.v4(); const token = new Token({ id: tokenId, wallet_id: walletId, - capture_id: captureId + capture_id: captureId, }); const token2 = new Token({ id: token2Id, wallet_id: wallet2Id, - capture_id: capture2Id + capture_id: capture2Id, }); const wallet = new Wallet(walletId); const wallet2 = new Wallet(wallet2Id); - - it("/test-uuid successfully", async () => { - sinon.stub(TokenService.prototype, "getById").resolves(token); - sinon.stub(WalletService.prototype, "getById").resolves(wallet); - sinon.stub(Wallet.prototype, "getSubWallets").resolves([]); - sinon.stub(TokenService.prototype, "convertToResponse").resolves({ + it('/test-uuid successfully', async () => { + sinon.stub(TokenService.prototype, 'getById').resolves(token); + sinon.stub(WalletService.prototype, 'getById').resolves(wallet); + sinon.stub(Wallet.prototype, 'getSubWallets').resolves([]); + sinon.stub(TokenService.prototype, 'convertToResponse').resolves({ token: tokenId, sender_wallet: walletId, receiver_wallet: wallet2Id, }); - const res = await request(app) - .get(`/${tokenId}`); - expect(res).property("statusCode").eq(200); - expect(res.body).property("id").eq(tokenId); - expect(res.body).property("links").property("capture").eq("/webmap/tree?uuid=" + captureId); + const res = await request(app).get(`/${tokenId}`); + expect(res).property('statusCode').eq(200); + expect(res.body).property('id').eq(tokenId); + expect(res.body) + .property('links') + .property('capture') + .eq(`/webmap/tree?uuid=${captureId}`); }); - it("/xxx/transactions successfully", async () => { - sinon.stub(TokenService.prototype, "getById").resolves(token); - sinon.stub(token, "toJSON").resolves({ + it('/xxx/transactions successfully', async () => { + sinon.stub(TokenService.prototype, 'getById').resolves(token); + sinon.stub(token, 'toJSON').resolves({ wallet_id: walletId, }); - sinon.stub(token, "getTransactions").resolves([{ - id: transactionId, - }]); - sinon.stub(WalletService.prototype, "getById").resolves(wallet); - sinon.stub(TokenService.prototype, "convertToResponse").resolves({ + sinon.stub(token, 'getTransactions').resolves([ + { + id: transactionId, + }, + ]); + sinon.stub(WalletService.prototype, 'getById').resolves(wallet); + sinon.stub(TokenService.prototype, 'convertToResponse').resolves({ token: tokenId, sender_wallet: walletId, receiver_wallet: wallet2Id, }); - sinon.stub(Wallet.prototype, "getSubWallets").resolves([]); - const res = await request(app) - .get(`/${tokenId}/transactions/?limit=1`); - expect(res).property("statusCode").eq(200); + sinon.stub(Wallet.prototype, 'getSubWallets').resolves([]); + const res = await request(app).get(`/${tokenId}/transactions/?limit=1`); + expect(res).property('statusCode').eq(200); expect(res.body.history).lengthOf(1); - expect(res.body.history[0]).property("token").eq(tokenId); - expect(res.body.history[0]).property("sender_wallet").eq(walletId); - expect(res.body.history[0]).property("receiver_wallet").eq(wallet2Id); + expect(res.body.history[0]).property('token').eq(tokenId); + expect(res.body.history[0]).property('sender_wallet').eq(walletId); + expect(res.body.history[0]).property('receiver_wallet').eq(wallet2Id); }); - it("/{token_uuid}/transactions: limit parameters missed", async () => { - const res = await request(app) - .get(`/${transactionId}/transactions`); - expect(res).property("statusCode").eq(422); + it('/{token_uuid}/transactions: limit parameters missed', async () => { + const res = await request(app).get(`/${transactionId}/transactions`); + expect(res).property('statusCode').eq(422); }); - it("/{token_uuid}/transactions limit and offset successfully", async () => { - sinon.stub(TokenService.prototype, "getById").resolves(token); - sinon.stub(token, "toJSON").resolves({ + it('/{token_uuid}/transactions limit and offset successfully', async () => { + sinon.stub(TokenService.prototype, 'getById').resolves(token); + sinon.stub(token, 'toJSON').resolves({ wallet_id: walletId, }); - sinon.stub(token, "getTransactions").resolves([ - {id: uuid.v4()}, {id: uuid.v4()}, {id: uuid.v4()}, {id: uuid.v4()}, {id: uuid.v4()}, {id: uuid.v4()}, {id: uuid.v4()}, {id: uuid.v4()}, {id: uuid.v4()}, {id: uuid.v4()} + const getTransactionsStub = sinon.stub(token, 'getTransactions'); + getTransactionsStub.resolves([ + { id: uuid.v4() }, + { id: uuid.v4() }, + { id: uuid.v4() }, + ]); + sinon.stub(WalletService.prototype, 'getById').resolves(wallet); + sinon + .stub(TokenService.prototype, 'convertToResponse') + .resolves({ + token: tokenId, + sender_wallet: authenticatedWallet, + receiver_wallet: wallet2Id, + }) + .onCall(0) + .resolves({ + token: tokenId, + sender_wallet: 'number5', + receiver_wallet: 'number5', + }) + .onCall(1) + .resolves({ + token: tokenId, + sender_wallet: 'number6', + receiver_wallet: 'number6', + }) + .onCall(2) + .resolves({ + token: tokenId, + sender_wallet: 'number7', + receiver_wallet: 'number7', + }); + sinon.stub(Wallet.prototype, 'getSubWallets').resolves([]); + + const limit = '3'; + const offset = '5'; + const res = await request(app).get( + `/${tokenId}/transactions?limit=${limit}&offset=${offset}`, + ); + expect(res).property('statusCode').eq(200); + expect(getTransactionsStub.getCall(0).args).deep.to.equal([ + limit, + offset, ]); - sinon.stub(WalletService.prototype, "getById").resolves(wallet); - sinon.stub(TokenService.prototype, "convertToResponse").resolves({ - token: tokenId, - sender_wallet: authenticatedWallet, - receiver_wallet: wallet2Id, - }).onCall(4).resolves({ - token: tokenId, - sender_wallet: "number5", - receiver_wallet: "number5", - }).onCall(5).resolves({ - token: tokenId, - sender_wallet: "number6", - receiver_wallet: "number6", - }).onCall(6).resolves({ - token: tokenId, - sender_wallet: "number7", - receiver_wallet: "number7", - }); - sinon.stub(Wallet.prototype, "getSubWallets").resolves([]); - const res = await request(app) - .get(`/${tokenId}/transactions?limit=3&start=5`); - expect(res).property("statusCode").eq(200); - expect(res.body.history).lengthOf(3); - expect(res.body.history[0]).property("sender_wallet").eq("number5"); - expect(res.body.history[0]).property("receiver_wallet").eq("number5"); - - expect(res.body.history[1]).property("sender_wallet").eq("number6"); - expect(res.body.history[1]).property("receiver_wallet").eq("number6"); - expect(res.body.history[2]).property("sender_wallet").eq("number7"); - expect(res.body.history[2]).property("receiver_wallet").eq("number7"); + expect(res.body.history).lengthOf(3); + expect(res.body.history[0]).property('sender_wallet').eq('number5'); + expect(res.body.history[0]).property('receiver_wallet').eq('number5'); + expect(res.body.history[1]).property('sender_wallet').eq('number6'); + expect(res.body.history[1]).property('receiver_wallet').eq('number6'); + expect(res.body.history[2]).property('sender_wallet').eq('number7'); + expect(res.body.history[2]).property('receiver_wallet').eq('number7'); }); }); - }); diff --git a/server/routes/transferRouter.js b/server/routes/transferRouter.js index de0fd7e3..365eacfe 100644 --- a/server/routes/transferRouter.js +++ b/server/routes/transferRouter.js @@ -1,18 +1,20 @@ -const express = require("express"); +const express = require('express'); + const transferRouter = express.Router(); -const WalletService = require("../services/WalletService"); -const TransferService = require("../services/TransferService"); -const Wallet = require("../models/Wallet"); -const TrustRelationship = require("../models/TrustRelationship"); -const helper = require("./utils"); -const Joi = require("joi"); -const TokenService = require("../services/TokenService"); -const HttpError = require("../utils/HttpError"); -const Transfer = require("../models/Transfer"); -const Session = require("../models/Session"); +const Joi = require('joi'); +const { assert } = require('joi'); +const WalletService = require('../services/WalletService'); +const TransferService = require('../services/TransferService'); +const Wallet = require('../models/Wallet'); +const TrustRelationship = require('../models/TrustRelationship'); +const helper = require('./utils'); +const TokenService = require('../services/TokenService'); +const HttpError = require('../utils/HttpError'); +const Transfer = require('../models/Transfer'); +const Session = require('../models/Session'); transferRouter.post( - "/", + '/', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { @@ -63,8 +65,8 @@ transferRouter.post( if(req.body.tokens){ const tokens = []; const tokenService = new TokenService(session); - for(let id of req.body.tokens){ - const token = await tokenService.getById(id); + for (const id of req.body.tokens) { + const token = await tokenService.getById(id); tokens.push(token); } // Case 1: with trust, token transfer @@ -76,14 +78,15 @@ transferRouter.post( } const transferService = new TransferService(session); result = await transferService.convertToResponse(result); - if(result.state === Transfer.STATE.completed){ + if (result.state === Transfer.STATE.completed) { res.status(201).json(result); - }else if( - result.state === Transfer.STATE.pending || - result.state === Transfer.STATE.requested){ + } else if ( + result.state === Transfer.STATE.pending || + result.state === Transfer.STATE.requested + ) { res.status(202).json(result); - }else{ - expect.fail(); + } else { + throw new Error(`Unexpected state ${result.state}`); } await session.commitTransaction(); }catch(e){ @@ -97,10 +100,11 @@ transferRouter.post( throw e; } } - }) + }), ); -transferRouter.post('/:transfer_id/accept', +transferRouter.post( + '/:transfer_id/accept', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { @@ -108,35 +112,39 @@ transferRouter.post('/:transfer_id/accept', req.params, Joi.object({ transfer_id: Joi.string().guid().required(), - }) + }), ); const session = new Session(); - //begin transaction - try{ + // begin transaction + try { await session.beginTransaction(); const walletService = new WalletService(session); const walletLogin = await walletService.getById(res.locals.wallet_id); - //TODO: claim + + // TODO: claim const transferJson = await walletLogin.acceptTransfer(req.params.transfer_id); const transferService = new TransferService(session); - const transferJson2 = await transferService.convertToResponse(transferJson); + const transferJson2 = await transferService.convertToResponse( + transferJson, + ); res.status(200).json(transferJson2); await session.commitTransaction(); - }catch(e){ - if(e instanceof HttpError && !e.shouldRollback()){ - //if the error type is HttpError, means the exception has been handled + } catch (e) { + if (e instanceof HttpError && !e.shouldRollback()) { + // if the error type is HttpError, means the exception has been handled await session.commitTransaction(); throw e; - }else{ - //unknown exception, rollback the transaction + } else { + // unknown exception, rollback the transaction await session.rollbackTransaction(); throw e; } } - }) + }), ); -transferRouter.post('/:transfer_id/decline', +transferRouter.post( + '/:transfer_id/decline', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { @@ -144,34 +152,39 @@ transferRouter.post('/:transfer_id/decline', req.params, Joi.object({ transfer_id: Joi.string().guid().required(), - }) + }), ); const session = new Session(); - //begin transaction - try{ + // begin transaction + try { await session.beginTransaction(); const walletService = new WalletService(session); const walletLogin = await walletService.getById(res.locals.wallet_id); - const transferJson = await walletLogin.declineTransfer(req.params.transfer_id); + const transferJson = await walletLogin.declineTransfer( + req.params.transfer_id, + ); const transferService = new TransferService(session); - const transferJson2 = await transferService.convertToResponse(transferJson); + const transferJson2 = await transferService.convertToResponse( + transferJson, + ); res.status(200).json(transferJson2); await session.commitTransaction(); - }catch(e){ - if(e instanceof HttpError && !e.shouldRollback()){ - //if the error type is HttpError, means the exception has been handled + } catch (e) { + if (e instanceof HttpError && !e.shouldRollback()) { + // if the error type is HttpError, means the exception has been handled await session.commitTransaction(); throw e; - }else{ - //unknown exception, rollback the transaction + } else { + // unknown exception, rollback the transaction await session.rollbackTransaction(); throw e; } } - }) + }), ); -transferRouter.delete('/:transfer_id', +transferRouter.delete( + '/:transfer_id', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { @@ -179,34 +192,39 @@ transferRouter.delete('/:transfer_id', req.params, Joi.object({ transfer_id: Joi.string().guid().required(), - }) + }), ); const session = new Session(); - //begin transaction - try{ + // begin transaction + try { await session.beginTransaction(); const walletService = new WalletService(session); const walletLogin = await walletService.getById(res.locals.wallet_id); - const transferJson = await walletLogin.cancelTransfer(req.params.transfer_id); + const transferJson = await walletLogin.cancelTransfer( + req.params.transfer_id, + ); const transferService = new TransferService(session); - const transferJson2 = await transferService.convertToResponse(transferJson); + const transferJson2 = await transferService.convertToResponse( + transferJson, + ); res.status(200).json(transferJson2); await session.commitTransaction(); - }catch(e){ - if(e instanceof HttpError && !e.shouldRollback()){ - //if the error type is HttpError, means the exception has been handled + } catch (e) { + if (e instanceof HttpError && !e.shouldRollback()) { + // if the error type is HttpError, means the exception has been handled await session.commitTransaction(); throw e; - }else{ - //unknown exception, rollback the transaction + } else { + // unknown exception, rollback the transaction await session.rollbackTransaction(); throw e; } } - }) + }), ); -transferRouter.post('/:transfer_id/fulfill', +transferRouter.post( + '/:transfer_id/fulfill', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { @@ -214,105 +232,116 @@ transferRouter.post('/:transfer_id/fulfill', req.params, Joi.object({ transfer_id: Joi.string().guid().required(), - }) + }), ); Joi.assert( req.body, Joi.alternatives() - //if there is tokens field - .conditional(Joi.object({ - tokens: Joi.any().required(), - }).unknown(),{ - then: Joi.object({ - tokens: Joi.array().items(Joi.string()).required().unique(), - }), - otherwise: Joi.object({ - implicit: Joi.boolean().truthy().required(), - }), - }) + // if there is tokens field + .conditional( + Joi.object({ + tokens: Joi.any().required(), + }).unknown(), + { + then: Joi.object({ + tokens: Joi.array().items(Joi.string()).required().unique(), + }), + otherwise: Joi.object({ + implicit: Joi.boolean().truthy().required(), + }), + }, + ), ); const session = new Session(); - //begin transaction - try{ + // begin transaction + try { await session.beginTransaction(); const walletService = new WalletService(session); const transferService = new TransferService(session); const walletLogin = await walletService.getById(res.locals.wallet_id); let transferJson; - if(req.body.implicit){ - transferJson = await walletLogin.fulfillTransfer(req.params.transfer_id); - }else{ - //load tokens + if (req.body.implicit) { + transferJson = await walletLogin.fulfillTransfer( + req.params.transfer_id, + ); + } else { + // load tokens const tokens = []; const tokenService = new TokenService(session); - for(let id of req.body.tokens){ - const token = await tokenService.getById(id); + for (const id of req.body.tokens) { + const token = await tokenService.getById(id); tokens.push(token); } - transferJson = await walletLogin.fulfillTransferWithTokens(req.params.transfer_id, tokens); + transferJson = await walletLogin.fulfillTransferWithTokens( + req.params.transfer_id, + tokens, + ); } - const transferJson2 = await transferService.convertToResponse(transferJson); + const transferJson2 = await transferService.convertToResponse( + transferJson, + ); res.status(200).json(transferJson2); await session.commitTransaction(); - }catch(e){ - if(e instanceof HttpError && !e.shouldRollback()){ - //if the error type is HttpError, means the exception has been handled + } catch (e) { + if (e instanceof HttpError && !e.shouldRollback()) { + // if the error type is HttpError, means the exception has been handled await session.commitTransaction(); throw e; - }else{ - //unknown exception, rollback the transaction + } else { + // unknown exception, rollback the transaction await session.rollbackTransaction(); throw e; } } - }) + }), ); -transferRouter.get("/", +transferRouter.get( + '/', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { Joi.assert( req.query, Joi.object({ - state: Joi.string() - .valid(...Object.values(Transfer.STATE)), + state: Joi.string().valid(...Object.values(Transfer.STATE)), wallet: Joi.alternatives().try( Joi.string(), - Joi.number().min(4).max(32) + Joi.number().min(4).max(32), ), - limit: Joi.number().required(), - start: Joi.number().min(1).max(10000).integer() - }) + limit: Joi.number().min(1).max(1000).required(), + offset: Joi.number().min(0).integer().default(0), + }), ); - const {state, wallet, limit, start} = req.query; + const { state, wallet, limit, offset } = req.query; const session = new Session(); const walletService = new WalletService(session); const walletLogin = await walletService.getById(res.locals.wallet_id); + let walletTransfer = walletLogin; - if(wallet){ + if (wallet) { walletTransfer = await walletService.getByIdOrName(wallet); } - - const result = await walletTransfer.getTransfers(state); + // todo fix filtering by wallet, instead of undefined should take a wallet object with getId() function + const result = await walletTransfer.getTransfers( + state, + undefined, + offset, + limit, + ); const transferService = new TransferService(session); - let json = []; - for(let t of result){ + const json = []; + for (const t of result) { const j = await transferService.convertToResponse(t); json.push(j); } - //filter tokensJson by query - let numStart = parseInt(start); - let numLimit = parseInt(limit); - let numBegin = numStart?numStart-1:0; - let numEnd=numBegin+numLimit; - json = json.slice(numBegin, numEnd); - res.status(200).json({transfers: json}); - }) + res.status(200).json({ transfers: json }); + }), ); -transferRouter.get('/:transfer_id', +transferRouter.get( + '/:transfer_id', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { @@ -320,19 +349,24 @@ transferRouter.get('/:transfer_id', req.params, Joi.object({ transfer_id: Joi.string().guid().required(), - }) + }), ); const session = new Session(); const walletService = new WalletService(session); const transferService = new TransferService(session); const walletLogin = await walletService.getById(res.locals.wallet_id); - const transferObject = await walletLogin.getTransferById(req.params.transfer_id); - const transferJson = await transferService.convertToResponse(transferObject); + const transferObject = await walletLogin.getTransferById( + req.params.transfer_id, + ); + const transferJson = await transferService.convertToResponse( + transferObject, + ); res.status(200).json(transferJson); - }) + }), ); -transferRouter.get('/:transfer_id/tokens', +transferRouter.get( + '/:transfer_id/tokens', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { @@ -340,36 +374,35 @@ transferRouter.get('/:transfer_id/tokens', req.params, Joi.object({ transfer_id: Joi.string().guid().required(), - }) + }), ); Joi.assert( req.query, Joi.object({ - limit: Joi.number().required(), - start: Joi.number().min(1).max(10000).integer(), - }) + limit: Joi.number().min(1).max(1000).required(), + offset: Joi.number().min(0).integer().default(0), + }), ); - const {limit, start} = req.query; + const { limit, offset } = req.query; const session = new Session(); const walletService = new WalletService(session); const walletLogin = await walletService.getById(res.locals.wallet_id); - const tokens = await walletLogin.getTokensByTransferId(req.params.transfer_id); - let tokensJson = []; - for(const token of tokens){ + const tokens = await walletLogin.getTokensByTransferId( + req.params.transfer_id, + Number(limit), + Number(offset || 0), + ); + + const tokensJson = []; + for (const token of tokens) { const json = await token.toJSON(); tokensJson.push(json); } - //filter tokensJson by query - let numStart = parseInt(start); - let numLimit = parseInt(limit); - let numBegin = numStart?numStart-1:0; - let numEnd=numBegin+numLimit; - tokensJson = tokensJson.slice(numBegin, numEnd); res.status(200).json({ tokens: tokensJson, }); - }) + }), ); module.exports = transferRouter; diff --git a/server/routes/transferRouter.spec.js b/server/routes/transferRouter.spec.js index b29921d6..5f7437f1 100644 --- a/server/routes/transferRouter.spec.js +++ b/server/routes/transferRouter.spec.js @@ -1,14 +1,17 @@ const request = require("supertest"); const express = require("express"); -const transferRouter = require("./transferRouter"); -const {errorHandler} = require("./utils"); const sinon = require("sinon"); const chai = require("chai"); const sinonChai = require("sinon-chai"); +const bodyParser = require('body-parser'); +const { extractExpectedAssertionsErrors } = require("expect"); +const uuid = require('uuid'); +const transferRouter = require("./transferRouter"); +const {errorHandler} = require("./utils"); + chai.use(sinonChai); const {expect} = chai; const ApiKeyService = require("../services/ApiKeyService"); -const bodyParser = require('body-parser'); const WalletService = require("../services/WalletService"); const JWTService = require("../services/JWTService"); const HttpError = require("../utils/HttpError"); @@ -18,13 +21,11 @@ const Wallet = require("../models/Wallet"); const Transfer = require("../models/Transfer"); const TransferService = require("../services/TransferService"); const Session = require("../models/Session"); -const { extractExpectedAssertionsErrors } = require("expect"); const { column } = require("../database/knex"); -const uuid = require('uuid'); describe("transferRouter", () => { let app; - let session = new Session(); + const session = new Session(); const authenticatedWallet = new Wallet(uuid.v4()) @@ -60,39 +61,25 @@ describe("transferRouter", () => { .stub(WalletService.prototype, 'getByIdOrName') .resolves(new Wallet(uuid.v4())); - sinon.stub(Wallet.prototype, 'getTransfers').resolves( - [{},{},{},{},{},{},{},{},{},{}].map((_,i) => ({id:uuid.v4(), state:Transfer.STATE.completed}) + const getTransfersStub = sinon.stub(Wallet.prototype, 'getTransfers') + getTransfersStub.resolves( + [{},{},{}].map((_,i) => ({id:uuid.v4(), state:Transfer.STATE.completed}) )); const token0Id = uuid.v4(); const token1Id = uuid.v4(); const token2Id = uuid.v4(); - const token3Id = uuid.v4(); - const token4Id = uuid.v4(); - const token5Id = uuid.v4(); - const token6Id = uuid.v4(); - const token7Id = uuid.v4(); - const token8Id = uuid.v4(); - const token9Id = uuid.v4(); sinon.stub(TransferService.prototype, "convertToResponse") .onCall(0).resolves({id:token0Id, state:Transfer.STATE.completed}) .onCall(1).resolves({id:token1Id, state:Transfer.STATE.completed}) - .onCall(2).resolves({id:token2Id, state:Transfer.STATE.completed}) - .onCall(3).resolves({id:token3Id, state:Transfer.STATE.completed}) - .onCall(4).resolves({id:token4Id, state:Transfer.STATE.completed}) - .onCall(5).resolves({id:token5Id, state:Transfer.STATE.completed}) - .onCall(6).resolves({id:token6Id, state:Transfer.STATE.completed}) - .onCall(7).resolves({id:token7Id, state:Transfer.STATE.completed}) - .onCall(8).resolves({id:token8Id, state:Transfer.STATE.completed}) - .onCall(9).resolves({id:token9Id, state:Transfer.STATE.completed}); + .onCall(2).resolves({id:token2Id, state:Transfer.STATE.completed}); const res = await request(app) - .get("/?limit=3&wallet=testWallet&start=5"); + .get("/?limit=3&wallet=testWallet&offset=5"); expect(res.body.transfers).lengthOf(3); - // console.log("HERE2"); - // console.log(res.body.transfers); - expect(res.body.transfers.map(t=>(t.id))).to.deep.equal([token4Id, token5Id, token6Id]); + expect(getTransfersStub.getCall(0).args[0]).to.deep.equal(undefined, 5, 3) + expect(res.body.transfers.map(t=>(t.id))).to.deep.equal([token0Id, token1Id, token2Id]); }); it("missing tokens should throw error", async () => { @@ -250,7 +237,7 @@ describe("transferRouter", () => { // expect(res).property('statusCode').eq(201); // }); - //check what's in the db, after transfer claim + // check what's in the db, after transfer claim // test transfer, in wallet.spec.js it("all parameters fine, but no trust relationship, should return 202", async () => { @@ -406,7 +393,7 @@ describe("transferRouter", () => { }); }); - describe("GET /{transfer_id}/tokens start and limit working", () => { + describe("GET /{transfer_id}/tokens offset and limit working", () => { const transferId = uuid.v4(); const tokenId = uuid.v4(); @@ -431,15 +418,16 @@ describe("transferRouter", () => { expect(res.body).property("tokens").lengthOf(1); }); - it("limit and start working successfully", async () => { + it("limit and offset working successfully", async () => { const fn = sinon.stub(WalletService.prototype, "getById").resolves(authenticatedWallet); - const fn2 = sinon.stub(Wallet.prototype, "getTokensByTransferId").resolves([token, token2, token3, token4]); + const fn2 = sinon.stub(Wallet.prototype, "getTokensByTransferId").resolves([token2, token3, token4]); const res = await request(app) - .get(`/${transferId}/tokens?limit=3&start=2`); + .get(`/${transferId}/tokens?limit=3&offset=2`); expect(fn).calledWith(authenticatedWallet.getId()); - expect(fn2).calledWith(transferId); + + expect(fn2).calledWith(transferId, 3, 2); expect(res).property("statusCode").eq(200); - console.log(res.body); + expect(res.body).property("tokens").lengthOf(3); expect(res.body.tokens.map(t=>(t.id))).to.deep.equal([token2.getId(), token3.getId(), token4.getId()]); }); diff --git a/server/routes/trustRouter.js b/server/routes/trustRouter.js index eddc8c44..e6fd7394 100644 --- a/server/routes/trustRouter.js +++ b/server/routes/trustRouter.js @@ -1,106 +1,105 @@ const express = require('express'); + const trustRouter = express.Router(); -const { check, validationResult } = require('express-validator'); -const assert = require("assert"); -const WalletService = require("../services/WalletService"); -const TrustService = require("../services/TrustService"); -const Wallet = require("../models/Wallet"); -const helper = require("./utils"); -const Session = require("../models/Session"); -const TrustRelationship = require("../models/TrustRelationship"); -const Joi = require("joi"); +const Joi = require('joi'); +const WalletService = require('../services/WalletService'); +const TrustService = require('../services/TrustService'); +const helper = require('./utils'); +const Session = require('../models/Session'); +const TrustRelationship = require('../models/TrustRelationship'); -trustRouter.get('/', +trustRouter.get( + '/', helper.apiKeyHandler, helper.verifyJWTHandler, - helper.handlerWrapper(async (req, res, next) => { + helper.handlerWrapper(async (req, res) => { Joi.assert( req.query, Joi.object({ state: Joi.string(), type: Joi.string(), request_type: Joi.string(), - start: Joi.number(), - limit: Joi.number().min(1).max(10000).integer(), - }) - ) + offset: Joi.number().min(0).default(0).integer(), + limit: Joi.number().min(1).max(1000).integer().default(1000), + }), + ); Joi.assert( res.locals, Joi.object({ - wallet_id: Joi.string().required() - }) - ) - const {state, type, request_type, limit, start} = req.query; + wallet_id: Joi.string().required(), + }), + ); + const { state, type, request_type, limit, offset } = req.query; const session = new Session(); const walletService = new WalletService(session); const trustService = new TrustService(session); const wallet = await walletService.getById(res.locals.wallet_id); const trust_relationships = await wallet.getTrustRelationships( - req.query.state, - req.query.type, - req.query.request_type, + state, + type, + request_type, + Number(offset || 0), + Number(limit || 0), ); const subWallets = await wallet.getSubWallets(); - for(const sw of subWallets){ + for (const sw of subWallets) { const trustRelationships = await sw.getTrustRelationships( req.query.state, req.query.type, req.query.request_type, ); - for(tr of trustRelationships){ - if(trust_relationships.every(e => e.id !== tr.id)){ + for (const tr of trustRelationships) { + if (trust_relationships.every((e) => e.id !== tr.id)) { trust_relationships.push(tr); } } } - let trust_relationships_json = []; - for(let t of trust_relationships){ + const trust_relationships_json = []; + for (const t of trust_relationships) { const j = await trustService.convertToResponse(t); trust_relationships_json.push(j); } - //filter trust_relationships json by query - let numStart = parseInt(start); - let numLimit = parseInt(limit) ? parseInt(limit) : 0; //TODO: fix this correctly by using db - let numBegin = numStart?numStart-1:0; - let numEnd = numBegin + ((numLimit != 0) ? numLimit : 1000); - if(numEnd != 0){ - trust_relationships_json = trust_relationships_json.slice(numBegin, numEnd); - } - res.status(200).json({ trust_relationships: trust_relationships_json, }); }), ); -trustRouter.post('/', +trustRouter.post( + '/', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { Joi.assert( req.body, Joi.object({ - trust_request_type: Joi.string().required().valid(...Object.keys(TrustRelationship.ENTITY_TRUST_REQUEST_TYPE)), + trust_request_type: Joi.string() + .required() + .valid(...Object.keys(TrustRelationship.ENTITY_TRUST_REQUEST_TYPE)), requestee_wallet: Joi.string().required(), - }) + }), ); Joi.assert( res.locals, Joi.object({ - wallet_id: Joi.string().required() - }) - ) - + wallet_id: Joi.string().required(), + }), + ); + const session = new Session(); const walletService = new WalletService(session); const trustService = new TrustService(session); const wallet = await walletService.getById(res.locals.wallet_id); - const requesteeWallet = await walletService.getByName(req.body.requestee_wallet); + const requesteeWallet = await walletService.getByName( + req.body.requestee_wallet, + ); let requesterWallet = wallet; - if(req.body.requester_wallet){ - requesterWallet = await walletService.getByName(req.body.requester_wallet); + if (req.body.requester_wallet) { + requesterWallet = await walletService.getByName( + req.body.requester_wallet, + ); } const trust_relationship = await wallet.requestTrustFromAWallet( @@ -108,28 +107,31 @@ trustRouter.post('/', requesterWallet, requesteeWallet, ); - const trust_relationship_json = await trustService.convertToResponse(trust_relationship); + const trust_relationship_json = await trustService.convertToResponse( + trust_relationship, + ); res.status(200).json(trust_relationship_json); - }) + }), ); -trustRouter.post('/:trustRelationshipId/accept', +trustRouter.post( + '/:trustRelationshipId/accept', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { Joi.assert( res.locals, Joi.object({ - wallet_id: Joi.string().required() - }) - ) + wallet_id: Joi.string().required(), + }), + ); Joi.assert( req.params, Joi.object({ - trustRelationshipId: Joi.string().required() - }) - ) - const trustRelationshipId = req.params.trustRelationshipId; + trustRelationshipId: Joi.string().required(), + }), + ); + const { trustRelationshipId } = req.params; const session = new Session(); const walletService = new WalletService(session); const trustService = new TrustService(session); @@ -137,26 +139,27 @@ trustRouter.post('/:trustRelationshipId/accept', const json = await wallet.acceptTrustRequestSentToMe(trustRelationshipId); const json2 = await trustService.convertToResponse(json); res.status(200).json(json2); - }) + }), ); -trustRouter.post('/:trustRelationshipId/decline', +trustRouter.post( + '/:trustRelationshipId/decline', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { Joi.assert( res.locals, Joi.object({ - wallet_id: Joi.string().required() - }) - ) + wallet_id: Joi.string().required(), + }), + ); Joi.assert( req.params, Joi.object({ - trustRelationshipId: Joi.string().required() - }) - ) - const trustRelationshipId = req.params.trustRelationshipId; + trustRelationshipId: Joi.string().required(), + }), + ); + const { trustRelationshipId } = req.params; const session = new Session(); const walletService = new WalletService(session); const trustService = new TrustService(session); @@ -164,26 +167,27 @@ trustRouter.post('/:trustRelationshipId/decline', const json = await wallet.declineTrustRequestSentToMe(trustRelationshipId); const json2 = await trustService.convertToResponse(json); res.status(200).json(json2); - }) + }), ); -trustRouter.delete('/:trustRelationshipId', +trustRouter.delete( + '/:trustRelationshipId', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res) => { Joi.assert( res.locals, Joi.object({ - wallet_id: Joi.string().required() - }) - ) + wallet_id: Joi.string().required(), + }), + ); Joi.assert( req.params, Joi.object({ - trustRelationshipId: Joi.string().required() - }) - ) - const trustRelationshipId = req.params.trustRelationshipId; + trustRelationshipId: Joi.string().required(), + }), + ); + const { trustRelationshipId } = req.params; const session = new Session(); const walletService = new WalletService(session); const trustService = new TrustService(session); @@ -191,7 +195,7 @@ trustRouter.delete('/:trustRelationshipId', const json = await wallet.cancelTrustRequestSentToMe(trustRelationshipId); const json2 = await trustService.convertToResponse(json); res.status(200).json(json2); - }) + }), ); module.exports = trustRouter; diff --git a/server/routes/trustRouter.spec.js b/server/routes/trustRouter.spec.js index 1d0e6585..d02ffa88 100644 --- a/server/routes/trustRouter.spec.js +++ b/server/routes/trustRouter.spec.js @@ -1,14 +1,16 @@ const request = require("supertest"); const express = require("express"); -const trustRouter = require("./trustRouter"); -const {errorHandler} = require("./utils"); const sinon = require("sinon"); const chai = require("chai"); const sinonChai = require("sinon-chai"); +const bodyParser = require('body-parser'); +const uuid = require('uuid'); +const trustRouter = require("./trustRouter"); +const {errorHandler} = require("./utils"); + chai.use(sinonChai); const {expect} = chai; const ApiKeyService = require("../services/ApiKeyService"); -const bodyParser = require('body-parser'); const WalletService = require("../services/WalletService"); const TrustService = require("../services/TrustService"); const JWTService = require("../services/JWTService"); @@ -17,7 +19,6 @@ const Token = require("../models/Token"); const TokenService = require("../services/TokenService"); const Wallet = require("../models/Wallet"); const TrustRelationship = require("../models/TrustRelationship"); -const uuid = require('uuid'); describe("trustRouter", () => { let app; @@ -123,30 +124,30 @@ describe("trustRouter", () => { // TODO: need to update the test sinon.stub(WalletService.prototype, "getById").resolves(new Wallet(walletId)); sinon.stub(TrustService.prototype, "convertToResponse").resolves({id:trustId}); - const fn = sinon.stub(Wallet.prototype, "getTrustRelationships").resolves([{},{},{},{}]); + const fn = sinon.stub(Wallet.prototype, "getTrustRelationships").resolves([{},{},{}]); const res = await request(app) .get(`/?type=${TrustRelationship.ENTITY_TRUST_TYPE.send}&request_type=${TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send}&state=${TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted}&limit=3`); - console.log(res.body); - expect(res).property("statusCode").eq(200); - console.log(res.body.trust_relationships); - //get 3 from 4 items - expect(res.body.trust_relationships).lengthOf(3); + expect(fn).calledWith( TrustRelationship.ENTITY_TRUST_STATE_TYPE.trusted, TrustRelationship.ENTITY_TRUST_TYPE.send, - TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send + TrustRelationship.ENTITY_TRUST_REQUEST_TYPE.send, + 0, + 3 ) + expect(res).property("statusCode").eq(200); + expect(res.body.trust_relationships).lengthOf(3); }); - //TODO + // TODO it.skip("wrong state string should throw 422", () => { }); - //TODO + // TODO it.skip("wrong type string should throw 422", () => { }); - //TODO + // TODO it.skip("wrong request_type string should throw 422", () => { }); diff --git a/server/routes/utils.js b/server/routes/utils.js index 5127ba47..38e661a1 100644 --- a/server/routes/utils.js +++ b/server/routes/utils.js @@ -2,10 +2,10 @@ * Some utils for router/express */ const log = require("loglevel"); +const {ValidationError} = require("joi"); const HttpError = require("../utils/HttpError"); const ApiKeyService = require("../services/ApiKeyService"); const JWTService = require("../services/JWTService.js"); -const {ValidationError} = require("joi"); const Session = require("../models/Session"); /* diff --git a/server/routes/utils.spec.js b/server/routes/utils.spec.js index 2455cb4d..1d4fa044 100644 --- a/server/routes/utils.spec.js +++ b/server/routes/utils.spec.js @@ -1,11 +1,11 @@ const request = require("supertest"); const express = require("express"); -//const {handlerWrapper, errorHandler} = require("./utils"); -const helper = require("./utils"); +// const {handlerWrapper, errorHandler} = require("./utils"); const {expect} = require("chai"); +const sinon = require("sinon"); +const helper = require("./utils"); const HttpError = require("../utils/HttpError"); const ApiKeyService = require("../services/ApiKeyService"); -const sinon = require("sinon"); const JWTService = require("../services/JWTService"); describe("routers/utils", () => { @@ -92,7 +92,7 @@ describe("routers/utils", () => { it("check failed, should get response with code 401", async () => { const app = express(); - //mock + // mock sinon.stub(ApiKeyService.prototype, "check").rejects(new HttpError(401)); app.get("/test", [ @@ -110,7 +110,7 @@ describe("routers/utils", () => { it("check passed, should get response with code 200", async () => { const app = express(); - //mock + // mock sinon.stub(ApiKeyService.prototype, "check").rejects(new HttpError(401)); app.get("/test", [ @@ -131,7 +131,7 @@ describe("routers/utils", () => { it("pass correct token should pass the verify", async () => { const app = express(); - //mock + // mock sinon.stub(ApiKeyService.prototype, "check").rejects(new HttpError(401)); app.get("/test", [ @@ -153,7 +153,7 @@ describe("routers/utils", () => { it("pass corupt token should get response with code 403", async () => { const app = express(); - //mock + // mock sinon.stub(ApiKeyService.prototype, "check").rejects(new HttpError(401)); app.get("/test", [ @@ -168,7 +168,7 @@ describe("routers/utils", () => { const token = jwt.sign(payload); const res = await request(app) .get("/test") - .set('Authorization', `Bearer ${token.slice(1)}`);//NOTE corupt here + .set('Authorization', `Bearer ${token.slice(1)}`);// NOTE corupt here expect(res.statusCode).eq(403); ApiKeyService.prototype.check.restore(); }); diff --git a/server/routes/walletRouter.js b/server/routes/walletRouter.js index adb165e2..0b70fc50 100644 --- a/server/routes/walletRouter.js +++ b/server/routes/walletRouter.js @@ -1,15 +1,16 @@ const express = require('express'); +const Joi = require('joi'); +const _ = require('lodash'); const helper = require('./utils'); -const WalletService = require("../services/WalletService"); -const TokenService = require("../services/TokenService"); -const TrustService = require("../services/TrustService"); -const Joi = require("joi"); -const Session = require("../models/Session"); -const _ = require('lodash') +const WalletService = require('../services/WalletService'); +const TokenService = require('../services/TokenService'); +const TrustService = require('../services/TrustService'); +const Session = require('../models/Session'); const walletRouter = express.Router(); -walletRouter.get('/', +walletRouter.get( + '/', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res, next) => { @@ -17,42 +18,44 @@ walletRouter.get('/', req.query, Joi.object({ limit: Joi.number().required(), - start: Joi.number().min(1).max(10000).integer(), - }) + offset: Joi.number().min(1).integer(), + }), ); - const {limit, start} = req.query; + const { limit, offset } = req.query; const session = new Session(); const walletService = new WalletService(session); const loggedInWallet = await walletService.getById(res.locals.wallet_id); const subWallets = await loggedInWallet.getSubWallets(); // at logged in wallets to list of wallets subWallets.push(loggedInWallet); - + let walletsJson = []; const tokenService = new TokenService(session); for (const wallet of subWallets) { const json = await wallet.toJSON(); - json.tokens_in_wallet = await tokenService.countTokenByWallet(wallet); + json.tokens_in_wallet = await tokenService.countTokenByWallet(wallet); walletsJson.push(json); } - - let numStart = parseInt(start); - let numLimit = parseInt(limit); - let numBegin = numStart?numStart-1:0; - let numEnd=numBegin+numLimit; - walletsJson = walletsJson.slice(numBegin, numEnd) - + + const numStart = parseInt(offset); + const numLimit = parseInt(limit); + const numBegin = numStart ? numStart - 1 : 0; + const numEnd = numBegin + numLimit; + walletsJson = walletsJson.slice(numBegin, numEnd); + res.status(200).json({ - wallets: walletsJson.map(wallet => _.omit(wallet, ['password', 'type', 'salt'])) + wallets: walletsJson.map((wallet) => + _.omit(wallet, ['password', 'type', 'salt']), + ), }); - }) + }), ); +// TO DO: Add below route to yaml -// TO DO: Add below route to yaml - -walletRouter.get('/:wallet_id/trust_relationships', +walletRouter.get( + '/:wallet_id/trust_relationships', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res, next) => { @@ -66,17 +69,18 @@ walletRouter.get('/:wallet_id/trust_relationships', req.query.request_type, ); const trust_relationships_json = []; - for(let t of trust_relationships){ + for (const t of trust_relationships) { const j = await trustService.convertToResponse(t); trust_relationships_json.push(j); } res.status(200).json({ trust_relationships: trust_relationships_json, }); - }) -); + }), +); -walletRouter.post('/', +walletRouter.post( + '/', helper.apiKeyHandler, helper.verifyJWTHandler, helper.handlerWrapper(async (req, res, next) => { @@ -84,7 +88,7 @@ walletRouter.post('/', req.body, Joi.object({ wallet: Joi.string().required(), - }) + }), ); const session = new Session(); const walletService = new WalletService(session); @@ -92,10 +96,9 @@ walletRouter.post('/', const addedWallet = await loggedInWallet.addManagedWallet(req.body.wallet); res.status(200).json({ - wallet: addedWallet.name + wallet: addedWallet.name, }); - }) -) - + }), +); module.exports = walletRouter; diff --git a/server/routes/walletRouter.spec.js b/server/routes/walletRouter.spec.js index 95592f17..ac317d2d 100644 --- a/server/routes/walletRouter.spec.js +++ b/server/routes/walletRouter.spec.js @@ -1,13 +1,15 @@ const request = require("supertest"); const express = require("express"); -const walletRouter = require("./walletRouter"); -const {errorHandler} = require("./utils"); const sinon = require("sinon"); const chai = require("chai"); const sinonChai = require("sinon-chai"); +const uuid = require('uuid'); +const bodyParser = require('body-parser'); +const walletRouter = require("./walletRouter"); +const {errorHandler} = require("./utils"); + chai.use(sinonChai); const {expect} = chai; -const bodyParser = require('body-parser'); const ApiKeyService = require("../services/ApiKeyService"); const WalletService = require("../services/WalletService"); const TokenService = require("../services/TokenService"); @@ -15,7 +17,6 @@ const TrustService = require("../services/TrustService"); const JWTService = require("../services/JWTService"); const HttpError = require("../utils/HttpError"); const Wallet = require("../models/Wallet"); -const uuid = require('uuid'); describe("walletRouter", ()=> { @@ -95,7 +96,7 @@ describe("walletRouter", ()=> { sinon.stub(TokenService.prototype, "countTokenByWallet").resolves(10); const fn = sinon.stub(Wallet.prototype, "getSubWallets").resolves([ mockWallet2, mockWallet3, mockWallet4]); const res = await request(app) - .get('/?limit=3&start=2'); + .get('/?limit=3&offset=2'); expect(res).property("statusCode").eq(200); expect(res.body.wallets).lengthOf(3); console.log(authenticatedWallet.getId()); diff --git a/server/server.js b/server/server.js index 21a5cb04..d1ea8143 100644 --- a/server/server.js +++ b/server/server.js @@ -1,11 +1,12 @@ require('dotenv').config() const log = require("loglevel"); -//setup log level +// setup log level require("./setup"); const app = require("./app"); + const port = process.env.NODE_PORT || 3006; app.listen(port,()=>{ - log.info('listening on port:' + port); + log.info(`listening on port:${ port}`); log.debug("debug log level!"); }); diff --git a/server/serverTest.js b/server/serverTest.js index 7c2fb2f8..08e0f4f4 100644 --- a/server/serverTest.js +++ b/server/serverTest.js @@ -1,18 +1,20 @@ /* * A test server for testing, seed some initial data into the DB */ -require('dotenv').config() -const app = require("./app"); +require('dotenv').config(); +const log = require('loglevel'); + +const app = require('./app'); + const port = process.env.NODE_PORT || 3006; const seed = require('../__tests__/seed'); -//set the log level -require("./setup"); -const log = require("loglevel"); +// set the log level +require('./setup'); -app.listen(port,async ()=>{ - log.info('listening on port:' + port); - log.info("Seed data"); - log.debug("debug log level!"); - await seed.clear(); - await seed.seed(); +app.listen(port, async () => { + log.info(`listening on port:${port}`); + log.info('Seed data'); + log.debug('debug log level!'); + await seed.clear(); + await seed.seed(); }); diff --git a/server/services/ApiKeyService.js b/server/services/ApiKeyService.js index 4d364b18..de5a2568 100644 --- a/server/services/ApiKeyService.js +++ b/server/services/ApiKeyService.js @@ -1,47 +1,45 @@ const FS = require('fs'); -const log = require("loglevel"); -const path = require("path"); -const HttpError = require("../utils/HttpError"); -const ApiKeyRepository = require("../repositories/ApiKeyRepository"); -const expect = require("expect-runtime"); +const log = require('loglevel'); +const path = require('path'); +const HttpError = require('../utils/HttpError'); +const ApiKeyRepository = require('../repositories/ApiKeyRepository'); // PRIVATE and PUBLIC key -const privateKEY = process.env.PRIVATE_KEY // FS.readFileSync(path.resolve(__dirname, '../../config/jwtRS256.key'), 'utf8'); -const publicKEY = process.env.PUBLIC_KEY // FS.readFileSync(path.resolve(__dirname, '../../config/jwtRS256.key.pub'), 'utf8'); +const privateKEY = process.env.PRIVATE_KEY; // FS.readFileSync(path.resolve(__dirname, '../../config/jwtRS256.key'), 'utf8'); +const publicKEY = process.env.PUBLIC_KEY; // FS.readFileSync(path.resolve(__dirname, '../../config/jwtRS256.key.pub'), 'utf8'); - -class ApiKeyService{ - constructor(session){ +class ApiKeyService { + constructor(session) { this.apiKeyRepository = new ApiKeyRepository(session); } - async check(apiKey){ + async check(apiKey) { if (!apiKey) { log.log('ERROR: Invalid access - no API key'); - throw new HttpError(401,'Invalid access - no API key'); + throw new HttpError(401, 'Invalid access - no API key'); } let result; - try{ + try { result = await this.apiKeyRepository.getByApiKey(apiKey); - }catch(e){ - if(e.code === 404){ - log.debug("404 -> 401"); - throw new HttpError(401,'Invalid API access'); - }else{ - log.debug("throw e:", e.message); + } catch (e) { + if (e.code === 404) { + log.debug('404 -> 401'); + throw new HttpError(401, 'Invalid API access'); + } else { + log.debug('throw e:', e.message); throw e; } } - if(result.tree_token_api_access === false){ - throw new HttpError(401,'Invalid API access, apiKey was deprecated'); + if (result.tree_token_api_access === false) { + throw new HttpError(401, 'Invalid API access, apiKey was deprecated'); } } } module.exports = ApiKeyService; -//const authController = {}; -//authController.apiKey = async (req, res, next) => { +// const authController = {}; +// authController.apiKey = async (req, res, next) => { // if (!req.headers['treetracker-api-key']) { // console.log('ERROR: Invalid access - no API key'); // next({ @@ -70,5 +68,4 @@ module.exports = ApiKeyService; // } // // console.log('Valid Access'); // next(); -//}; - +// }; diff --git a/server/services/ApiKeyService.spec.js b/server/services/ApiKeyService.spec.js index 70f275e8..368b34d1 100644 --- a/server/services/ApiKeyService.spec.js +++ b/server/services/ApiKeyService.spec.js @@ -1,6 +1,6 @@ -const ApiKeyService = require("./ApiKeyService"); const jestExpect = require("expect"); const sinon = require("sinon"); +const ApiKeyService = require("./ApiKeyService"); const ApiKeyRepository = require("../repositories/ApiKeyRepository"); const HttpError = require("../utils/HttpError"); const Session = require("../models/Session"); diff --git a/server/services/JWTService.js b/server/services/JWTService.js index 389335cb..101063b9 100644 --- a/server/services/JWTService.js +++ b/server/services/JWTService.js @@ -1,42 +1,43 @@ /* ________________________________________________________________________ * JWT Issuance upon prior authorization, login * ________________________________________________________________________ -*/ + */ const JWTTools = require('jsonwebtoken'); const Crypto = require('crypto'); const FS = require('fs'); -const log = require("loglevel"); -const path = require("path"); -const HttpError = require("../utils/HttpError"); +const log = require('loglevel'); +const path = require('path'); +const HttpError = require('../utils/HttpError'); // PRIVATE and PUBLIC key -const privateKEY = process.env.PRIVATE_KEY //FS.readFileSync(path.resolve(__dirname, '../../config/jwtRS256.key'), 'utf8'); -const publicKEY = process.env.PUBLIC_KEY //FS.readFileSync(path.resolve(__dirname, '../../config/jwtRS256.key.pub'), 'utf8'); +const privateKEY = process.env.PRIVATE_KEY; // FS.readFileSync(path.resolve(__dirname, '../../config/jwtRS256.key'), 'utf8'); +const publicKEY = process.env.PUBLIC_KEY; // FS.readFileSync(path.resolve(__dirname, '../../config/jwtRS256.key.pub'), 'utf8'); const signingOptions = { - issuer: "greenstand", - expiresIn: "365d", - algorithm: "RS256", + issuer: 'greenstand', + expiresIn: '365d', + algorithm: 'RS256', }; const verifyOptions = { - issuer: "greenstand", - expiresIn: "365d", - algorithms: ["RS256"], + issuer: 'greenstand', + expiresIn: '365d', + algorithms: ['RS256'], }; - -class JWTService{ - - sign(payload){ +class JWTService { + sign(payload) { return JWTTools.sign(payload, privateKEY, signingOptions); } verify(authorization) { if (!authorization) { - throw (403, 'ERROR: Authentication, no token supplied for protected path'); + throw new Error( + 403, + 'ERROR: Authentication, no token supplied for protected path', + ); } - //accounts for the "Bearer" string before the token + // accounts for the "Bearer" string before the token const tokenArray = authorization.split(' '); const token = tokenArray[1]; let result; @@ -49,12 +50,11 @@ class JWTService{ } result = decod; }); - }else{ + } else { throw new HttpError(403, 'ERROR: Authentication, token not verified'); } return result; } - } module.exports = JWTService; diff --git a/server/services/JWTService.spec.js b/server/services/JWTService.spec.js index 3dbfe68d..fce096d0 100644 --- a/server/services/JWTService.spec.js +++ b/server/services/JWTService.spec.js @@ -1,5 +1,5 @@ -const JWTService = require("./JWTService"); const {expect} = require("chai"); +const JWTService = require("./JWTService"); diff --git a/server/services/TokenService.js b/server/services/TokenService.js index 468b4f05..049429d1 100644 --- a/server/services/TokenService.js +++ b/server/services/TokenService.js @@ -1,8 +1,8 @@ +const log = require("loglevel"); +const Joi = require("joi"); const Token = require("../models/Token"); const TokenRepository = require("../repositories/TokenRepository"); const TransactionRepository = require("../repositories/TransactionRepository"); -const log = require("loglevel"); -const Joi = require("joi"); class TokenService{ @@ -10,7 +10,7 @@ class TokenService{ this._session = session this.tokenRepository = new TokenRepository(session); this.transactionRepository = new TransactionRepository(session); - const WalletService = require("../services/WalletService"); + const WalletService = require("./WalletService"); this.walletService = new WalletService(session); } @@ -20,18 +20,17 @@ class TokenService{ return token; } - async getByOwner(wallet){ + async getByOwner(wallet, limit, offset){ const tokensObject = await this.tokenRepository.getByFilter({ wallet_id: wallet.getId(), - }); - const tokens = tokensObject.map(object => new Token(object, this._session)); - return tokens; + }, {limit, offset}); + return tokensObject.map(object => new Token(object, this._session)); } - async getTokensByPendingTransferId(transferId){ + async getTokensByPendingTransferId(transferId, limit, offset = 0){ const result = await this.tokenRepository.getByFilter({ transfer_pending_id: transferId, - }); + }, {limit, offset}); return result.map(object => { return new Token(object, this._session); }); @@ -42,7 +41,7 @@ class TokenService{ */ async getTokensByBundle(wallet, bundleSize, claimBoolean){ console.log(claimBoolean); - //TODO: getByFilter should be able to handle claim boolean + // TODO: getByFilter should be able to handle claim boolean const result = await this.tokenRepository.getByFilter({ wallet_id: wallet.getId(), transfer_pending: false, @@ -103,8 +102,8 @@ class TokenService{ return result; } - async getTokensByTransferId(transferId){ - const result = await this.tokenRepository.getByTransferId(transferId); + async getTokensByTransferId(transferId, limit, offset = 0){ + const result = await this.tokenRepository.getByTransferId(transferId, limit, offset); const tokens = []; for(const r of result){ const token = new Token(r); diff --git a/server/services/TokenService.spec.js b/server/services/TokenService.spec.js index 992c73ed..3d8b4605 100644 --- a/server/services/TokenService.spec.js +++ b/server/services/TokenService.spec.js @@ -1,22 +1,23 @@ -const TokenService = require("./TokenService"); const sinon = require("sinon"); -const TokenRepository = require("../repositories/TokenRepository"); -const HttpError = require("../utils/HttpError"); const jestExpect = require("expect"); const chai = require("chai"); const sinonChai = require("sinon-chai"); +const uuid = require('uuid'); +const TokenService = require("./TokenService"); +const TokenRepository = require("../repositories/TokenRepository"); +const HttpError = require("../utils/HttpError"); + chai.use(sinonChai); const {expect} = chai; const Wallet = require("../models/Wallet"); const Token = require("../models/Token"); -const WalletService = require("../services/WalletService"); +const WalletService = require("./WalletService"); const Session = require("../models/Session"); const TransactionRepository = require("../repositories/TransactionRepository"); -const uuid = require('uuid'); describe("Token", () => { let tokenService; - let session = new Session(); + const session = new Session(); beforeEach(() => { tokenService = new TokenService(); diff --git a/server/services/TransferService.js b/server/services/TransferService.js index 322dd728..1097f923 100644 --- a/server/services/TransferService.js +++ b/server/services/TransferService.js @@ -1,20 +1,18 @@ -const WalletService = require("./WalletService"); -const expect = require("expect-runtime"); +const WalletService = require('./WalletService'); -class TransferService{ - - constructor(session){ +class TransferService { + constructor(session) { this._session = session; this.walletService = new WalletService(session); } - async convertToResponse(transferObject){ + async convertToResponse(transferObject) { const { originator_wallet_id, source_wallet_id, - destination_wallet_id + destination_wallet_id, } = transferObject; - const result = {...transferObject}; + const result = { ...transferObject }; { const wallet = await this.walletService.getById(originator_wallet_id); const json = await wallet.toJSON(); @@ -35,7 +33,6 @@ class TransferService{ } return result; } - } module.exports = TransferService; diff --git a/server/services/TransferService.spec.js b/server/services/TransferService.spec.js index 2a1e16f9..53412797 100644 --- a/server/services/TransferService.spec.js +++ b/server/services/TransferService.spec.js @@ -1,28 +1,28 @@ -const TransferService = require("./TransferService"); -const WalletService = require("./WalletService"); -const Wallet = require("../models/Wallet"); -const jestExpect = require("expect"); -const sinon = require("sinon"); -const chai = require("chai"); -const sinonChai = require("sinon-chai"); -chai.use(sinonChai); -const {expect} = chai; -const Session = require("../models/Session"); const uuid = require('uuid'); +const sinon = require('sinon'); +const chai = require('chai'); +const sinonChai = require('sinon-chai'); -describe("TransferService", () => { - let transferService ; - describe("", () => { - let session = new Session(); - transferService = new TransferService(session); +const TransferService = require('./TransferService'); +const WalletService = require('./WalletService'); +chai.use(sinonChai); +const { expect } = chai; +const Session = require('../models/Session'); +const Wallet = require('../models/Wallet'); + +describe('TransferService', () => { + let transferService; + describe('', () => { + const session = new Session(); + transferService = new TransferService(session); }); afterEach(() => { sinon.restore(); }); - it("convertToResponse", async () => { + it('convertToResponse', async () => { const transferId1 = uuid.v4(); const walletId1 = uuid.v4(); const transferObject = { @@ -30,15 +30,17 @@ describe("TransferService", () => { originator_wallet_id: walletId1, source_wallet_id: walletId1, destination_wallet_id: walletId1, - } - sinon.stub(WalletService.prototype, "getById").resolves(new Wallet({ - id: walletId1, - name: "testName", - })); + }; + sinon.stub(WalletService.prototype, 'getById').resolves( + new Wallet({ + id: walletId1, + name: 'testName', + }), + ); const result = await transferService.convertToResponse(transferObject); - console.warn("xxx:", result); - expect(result).property("source_wallet").eq("testName"); - expect(result).property("originating_wallet").eq("testName"); - expect(result).property("destination_wallet").eq("testName"); + console.warn('xxx:', result); + expect(result).property('source_wallet').eq('testName'); + expect(result).property('originating_wallet').eq('testName'); + expect(result).property('destination_wallet').eq('testName'); }); }); diff --git a/server/services/TrustService.js b/server/services/TrustService.js index d34e92d5..9c49346b 100644 --- a/server/services/TrustService.js +++ b/server/services/TrustService.js @@ -1,11 +1,10 @@ const WalletService = require("./WalletService"); -const expect = require("expect-runtime"); const Session = require("../models/Session"); class TrustService{ constructor(){ - let session = new Session(); + const session = new Session(); this.walletService = new WalletService(session); } diff --git a/server/services/TrustService.spec.js b/server/services/TrustService.spec.js index bae5dda5..5940de1e 100644 --- a/server/services/TrustService.spec.js +++ b/server/services/TrustService.spec.js @@ -5,12 +5,13 @@ const jestExpect = require("expect"); const sinon = require("sinon"); const chai = require("chai"); const sinonChai = require("sinon-chai"); + chai.use(sinonChai); const {expect} = chai; const uuid = require('uuid'); describe("TrustService", () => { - let trustService = new TrustService(); + const trustService = new TrustService(); describe("", () => { }); diff --git a/server/services/WalletService.js b/server/services/WalletService.js index ac6b1ddb..85ebeab8 100644 --- a/server/services/WalletService.js +++ b/server/services/WalletService.js @@ -1,8 +1,7 @@ +const { validate: uuidValidate } = require('uuid'); const WalletRepository = require('../repositories/WalletRepository'); const Wallet = require('../models/Wallet'); const HttpError = require("../utils/HttpError"); -const expect = require('expect-runtime'); -const { validate: uuidValidate } = require('uuid'); class WalletService { constructor(session){ diff --git a/server/services/WalletService.spec.js b/server/services/WalletService.spec.js index 408499c0..6ae0e851 100644 --- a/server/services/WalletService.spec.js +++ b/server/services/WalletService.spec.js @@ -1,14 +1,14 @@ -const WalletService = require("./WalletService"); -const WalletRepository = require("../repositories/WalletRepository"); const sinon = require("sinon"); const {expect} = require("chai"); +const uuid = require('uuid'); +const WalletService = require("./WalletService"); +const WalletRepository = require("../repositories/WalletRepository"); const Wallet = require("../models/Wallet"); const Session = require("../models/Session"); -const uuid = require('uuid'); describe("WalletService", () => { let walletService; - let session = new Session(); + const session = new Session(); beforeEach(() => { walletService = new WalletService(session); diff --git a/server/setup.js b/server/setup.js index 4415e9f9..b4d205eb 100644 --- a/server/setup.js +++ b/server/setup.js @@ -2,6 +2,7 @@ * A file to setup some global setting, like log level */ const log = require("loglevel"); + if(process.env.NODE_LOG_LEVEL){ log.setDefaultLevel(process.env.NODE_LOG_LEVEL); }else{ @@ -10,20 +11,46 @@ if(process.env.NODE_LOG_LEVEL){ const http = require('http') +const _sendNextMessage = function(message){ + + const options = { + hostname: '104.131.78.177', + port: 8000, + path: '/treetracker-wallet-api/log', + method: 'POST', + headers: { + 'Content-Type': 'text/plain', + } + } + + const req = http.request(options, res => { + res.on('data', d => { + process.stdout.write(d) + }) + }) + + req.write(message) -var loglevelServerSend = function(logger,options) { + + req.on('error', error => { + console.error(error) + }) + +req.end() +} +const loglevelServerSend = function(logger,options) { if (!logger || !logger.methodFactory) throw new Error('loglevel instance has to be specified in order to be extended') - var _url = options && options.url || 'http://localhost:8000/main/log', - _callOriginal = options && options.callOriginal || false, - _prefix = options && options.prefix, - _originalFactory = logger.methodFactory, - _sendQueue = [], - _isSending = false + const _url = options && options.url || 'http://localhost:8000/main/log'; + const _callOriginal = options && options.callOriginal || false; + const _prefix = options && options.prefix; + const _originalFactory = logger.methodFactory; + const _sendQueue = []; + const _isSending = false logger.methodFactory = function (methodName, logLevel, loggerName) { - var rawMethod = _originalFactory(methodName, logLevel) + const rawMethod = _originalFactory(methodName, logLevel) return function (message) { if (typeof _prefix === 'string') @@ -31,59 +58,19 @@ var loglevelServerSend = function(logger,options) { else if (typeof _prefix === 'function') message = _prefix(methodName,message) else - message = methodName + ': ' + message + message = `${methodName }: ${ message}` if (_callOriginal) rawMethod(message) - // _sendQueue.push(message) _sendNextMessage(message) } } logger.setLevel(logger.levels.DEBUG) - - var _sendNextMessage = function(message){ - -/* if (!_sendQueue.length || _isSending) - console.log('skpping') - return - - _isSending = true - */ - - /* - var msg = _sendQueue.shift(), - */ - - const options = { - hostname: '104.131.78.177', - port: 8000, - path: '/treetracker-wallet-api/log', - method: 'POST', - headers: { - 'Content-Type': 'text/plain', - } - } - - const req = http.request(options, res => { - res.on('data', d => { - process.stdout.write(d) - }) - }) - - req.write(message) - - - req.on('error', error => { - console.error(error) - }) - - req.end() - } } if(process.env.REMOTE_LOG_URL){ - console.log("Using remote log endpoint: " + process.env.REMOTE_LOG_URL) + console.log(`Using remote log endpoint: ${ process.env.REMOTE_LOG_URL}`) loglevelServerSend(log,{url:process.env.REMOTE_LOG_URL}) } diff --git a/server/utils/HttpError.js b/server/utils/HttpError.js index 16d0695d..908f303a 100644 --- a/server/utils/HttpError.js +++ b/server/utils/HttpError.js @@ -9,8 +9,8 @@ class HttpError extends Error { constructor(code, message, toRollback){ super(message); this.code = code; - //set rollback flag, so the transaction of db would rollback when catch this error - //set default to true + // set rollback flag, so the transaction of db would rollback when catch this error + // set default to true this._toRollback = toRollback || true; } diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..afdce847 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,5231 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/code-frame@^7.0.0": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== + dependencies: + "@babel/highlight" "^7.12.13" + +"@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" + integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/runtime@^7.11.2": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" + integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== + dependencies: + regenerator-runtime "^0.13.4" + +"@commitlint/cli@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-11.0.0.tgz#698199bc52afed50aa28169237758fa14a67b5d3" + integrity sha512-YWZWg1DuqqO5Zjh7vUOeSX76vm0FFyz4y0cpGMFhrhvUi5unc4IVfCXZ6337R9zxuBtmveiRuuhQqnRRer+13g== + dependencies: + "@babel/runtime" "^7.11.2" + "@commitlint/format" "^11.0.0" + "@commitlint/lint" "^11.0.0" + "@commitlint/load" "^11.0.0" + "@commitlint/read" "^11.0.0" + chalk "4.1.0" + core-js "^3.6.1" + get-stdin "8.0.0" + lodash "^4.17.19" + resolve-from "5.0.0" + resolve-global "1.0.0" + yargs "^15.1.0" + +"@commitlint/config-conventional@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-11.0.0.tgz#3fa300a1b639273946de3c3f15e1cda518333422" + integrity sha512-SNDRsb5gLuDd2PL83yCOQX6pE7gevC79UPFx+GLbLfw6jGnnbO9/tlL76MLD8MOViqGbo7ZicjChO9Gn+7tHhA== + dependencies: + conventional-changelog-conventionalcommits "^4.3.1" + +"@commitlint/ensure@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-11.0.0.tgz#3e796b968ab5b72bc6f8a6040076406306c987fb" + integrity sha512-/T4tjseSwlirKZdnx4AuICMNNlFvRyPQimbZIOYujp9DSO6XRtOy9NrmvWujwHsq9F5Wb80QWi4WMW6HMaENug== + dependencies: + "@commitlint/types" "^11.0.0" + lodash "^4.17.19" + +"@commitlint/execute-rule@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-11.0.0.tgz#3ed60ab7a33019e58d90e2d891b75d7df77b4b4d" + integrity sha512-g01p1g4BmYlZ2+tdotCavrMunnPFPhTzG1ZiLKTCYrooHRbmvqo42ZZn4QMStUEIcn+jfLb6BRZX3JzIwA1ezQ== + +"@commitlint/format@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-11.0.0.tgz#ac47b0b9ca46540c0082c721b290794e67bdc51b" + integrity sha512-bpBLWmG0wfZH/svzqD1hsGTpm79TKJWcf6EXZllh2J/LSSYKxGlv967lpw0hNojme0sZd4a/97R3qA2QHWWSLg== + dependencies: + "@commitlint/types" "^11.0.0" + chalk "^4.0.0" + +"@commitlint/is-ignored@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-11.0.0.tgz#7b803eda56276dbe7fec51eb1510676198468f39" + integrity sha512-VLHOUBN+sOlkYC4tGuzE41yNPO2w09sQnOpfS+pSPnBFkNUUHawEuA44PLHtDvQgVuYrMAmSWFQpWabMoP5/Xg== + dependencies: + "@commitlint/types" "^11.0.0" + semver "7.3.2" + +"@commitlint/lint@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-11.0.0.tgz#01e062cd1b0e7c3d756aa2c246462e0b6a3348a4" + integrity sha512-Q8IIqGIHfwKr8ecVZyYh6NtXFmKw4YSEWEr2GJTB/fTZXgaOGtGFZDWOesCZllQ63f1s/oWJYtVv5RAEuwN8BQ== + dependencies: + "@commitlint/is-ignored" "^11.0.0" + "@commitlint/parse" "^11.0.0" + "@commitlint/rules" "^11.0.0" + "@commitlint/types" "^11.0.0" + +"@commitlint/load@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-11.0.0.tgz#f736562f0ffa7e773f8808fea93319042ee18211" + integrity sha512-t5ZBrtgvgCwPfxmG811FCp39/o3SJ7L+SNsxFL92OR4WQxPcu6c8taD0CG2lzOHGuRyuMxZ7ps3EbngT2WpiCg== + dependencies: + "@commitlint/execute-rule" "^11.0.0" + "@commitlint/resolve-extends" "^11.0.0" + "@commitlint/types" "^11.0.0" + chalk "4.1.0" + cosmiconfig "^7.0.0" + lodash "^4.17.19" + resolve-from "^5.0.0" + +"@commitlint/message@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-11.0.0.tgz#83554c3cbbc884fd07b473593bc3e94bcaa3ee05" + integrity sha512-01ObK/18JL7PEIE3dBRtoMmU6S3ecPYDTQWWhcO+ErA3Ai0KDYqV5VWWEijdcVafNpdeUNrEMigRkxXHQLbyJA== + +"@commitlint/parse@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-11.0.0.tgz#d18b08cf67c35d02115207d7009306a2e8e7c901" + integrity sha512-DekKQAIYWAXIcyAZ6/PDBJylWJ1BROTfDIzr9PMVxZRxBPc1gW2TG8fLgjZfBP5mc0cuthPkVi91KQQKGri/7A== + dependencies: + conventional-changelog-angular "^5.0.0" + conventional-commits-parser "^3.0.0" + +"@commitlint/read@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-11.0.0.tgz#f24240548c63587bba139fa5a364cab926077016" + integrity sha512-37V0V91GSv0aDzMzJioKpCoZw6l0shk7+tRG8RkW1GfZzUIytdg3XqJmM+IaIYpaop0m6BbZtfq+idzUwJnw7g== + dependencies: + "@commitlint/top-level" "^11.0.0" + fs-extra "^9.0.0" + git-raw-commits "^2.0.0" + +"@commitlint/resolve-extends@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-11.0.0.tgz#158ecbe27d4a2a51d426111a01478e216fbb1036" + integrity sha512-WinU6Uv6L7HDGLqn/To13KM1CWvZ09VHZqryqxXa1OY+EvJkfU734CwnOEeNlSCK7FVLrB4kmodLJtL1dkEpXw== + dependencies: + import-fresh "^3.0.0" + lodash "^4.17.19" + resolve-from "^5.0.0" + resolve-global "^1.0.0" + +"@commitlint/rules@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-11.0.0.tgz#bdb310cc6fc55c9f8d7d917a22b69055c535c375" + integrity sha512-2hD9y9Ep5ZfoNxDDPkQadd2jJeocrwC4vJ98I0g8pNYn/W8hS9+/FuNpolREHN8PhmexXbkjrwyQrWbuC0DVaA== + dependencies: + "@commitlint/ensure" "^11.0.0" + "@commitlint/message" "^11.0.0" + "@commitlint/to-lines" "^11.0.0" + "@commitlint/types" "^11.0.0" + +"@commitlint/to-lines@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-11.0.0.tgz#86dea151c10eea41e39ea96fa4de07839258a7fe" + integrity sha512-TIDTB0Y23jlCNubDROUVokbJk6860idYB5cZkLWcRS9tlb6YSoeLn1NLafPlrhhkkkZzTYnlKYzCVrBNVes1iw== + +"@commitlint/top-level@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-11.0.0.tgz#bb2d1b6e5ed3be56874633b59e1f7de118c32783" + integrity sha512-O0nFU8o+Ws+py5pfMQIuyxOtfR/kwtr5ybqTvR+C2lUPer2x6lnQU+OnfD7hPM+A+COIUZWx10mYQvkR3MmtAA== + dependencies: + find-up "^5.0.0" + +"@commitlint/types@^11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-11.0.0.tgz#719cf05fcc1abb6533610a2e0f5dd1e61eac14fe" + integrity sha512-VoNqai1vR5anRF5Tuh/+SWDFk7xi7oMwHrHrbm1BprYXjB2RJsWLhUrStMssDxEl5lW/z3EUdg8RvH/IUBccSQ== + +"@eslint/eslintrc@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.0.tgz#99cc0a0584d72f1df38b900fb062ba995f395547" + integrity sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@hapi/hoek@^9.0.0": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.1.tgz#9daf5745156fd84b8e9889a2dc721f0c58e894aa" + integrity sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw== + +"@hapi/topo@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7" + integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + +"@sentry/core@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" + integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/hub@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" + integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== + dependencies: + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/minimal@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" + integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/types" "5.30.0" + tslib "^1.9.3" + +"@sentry/node@^5.1.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" + integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== + dependencies: + "@sentry/core" "5.30.0" + "@sentry/hub" "5.30.0" + "@sentry/tracing" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + cookie "^0.4.1" + https-proxy-agent "^5.0.0" + lru_map "^0.3.3" + tslib "^1.9.3" + +"@sentry/tracing@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" + integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== + dependencies: + "@sentry/hub" "5.30.0" + "@sentry/minimal" "5.30.0" + "@sentry/types" "5.30.0" + "@sentry/utils" "5.30.0" + tslib "^1.9.3" + +"@sentry/types@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" + integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== + +"@sentry/utils@5.30.0": + version "5.30.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" + integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== + dependencies: + "@sentry/types" "5.30.0" + tslib "^1.9.3" + +"@sideway/address@^4.1.0": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.1.tgz#9e321e74310963fdf8eebfbee09c7bd69972de4d" + integrity sha512-+I5aaQr3m0OAmMr7RQ3fR9zx55sejEYR2BFJaxL+zT3VM2611X0SHvPWIbAUBZVTn/YzYKbV8gJ2oT/QELknfQ== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@sideway/formula@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c" + integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg== + +"@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.1": + version "1.8.2" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.2.tgz#858f5c4b48d80778fde4b9d541f27edc0d56488b" + integrity sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^6.0.0", "@sinonjs/fake-timers@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" + integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@sinonjs/samsam@^5.3.1": + version "5.3.1" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f" + integrity sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg== + dependencies: + "@sinonjs/commons" "^1.6.0" + lodash.get "^4.4.2" + type-detect "^4.0.8" + +"@sinonjs/text-encoding@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" + integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@types/chai@4": + version "4.2.15" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.15.tgz#b7a6d263c2cecf44b6de9a051cf496249b154553" + integrity sha512-rYff6FI+ZTKAPkJUoyz7Udq3GaoDZnxYDEvdEdFZASiA7PoErltHezDishqQiSDWrGxvxmplH304jyzQmjp0AQ== + +"@types/cookiejar@*": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.2.tgz#66ad9331f63fe8a3d3d9d8c6e3906dd10f6446e8" + integrity sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762" + integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" + integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= + +"@types/minimist@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" + integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== + +"@types/node@*": + version "14.14.36" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.36.tgz#5637905dbb15c30a33a3c65b9ef7c20e3c85ebad" + integrity sha512-kjivUwDJfIjngzbhooRnOLhGYz6oRFi+L+EpMjxroDYXwDw9lHrJJ43E+dJ6KAd3V3WxWAJ/qZE9XKYHhjPOFQ== + +"@types/normalize-package-data@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/stack-utils@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" + integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== + +"@types/superagent@^3.8.3": + version "3.8.7" + resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-3.8.7.tgz#1f1ed44634d5459b3a672eb7235a8e7cfd97704c" + integrity sha512-9KhCkyXv268A2nZ1Wvu7rQWM+BmdYUVkycFeNnYrUL5Zwu7o8wPQ3wBfW59dDP+wuoxw0ww8YKgTNv8j/cgscA== + dependencies: + "@types/cookiejar" "*" + "@types/node" "*" + +"@types/yargs-parser@*": + version "20.2.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" + integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== + +"@types/yargs@^15.0.0": + version "15.0.13" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" + integrity sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ== + dependencies: + "@types/yargs-parser" "*" + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +JSONStream@^1.0.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-jsx@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + +acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^7.0.2: + version "7.2.4" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-7.2.4.tgz#8e239d4d56cf884bccca8cca362f508446dc160f" + integrity sha512-nBeQgg/ZZA3u3SYxyaDvpvDtgZ/EZPF547ARgZBrG9Bhu1vKDwAIjtIf+sDtJUKa2zOcEbmRLBRSyMraS/Oy1A== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-align@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" + integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== + dependencies: + string-width "^3.0.0" + +ansi-colors@4.1.1, ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-ify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= + +array-includes@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" + integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + get-intrinsic "^1.1.1" + is-string "^1.0.5" + +array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +array.prototype.flat@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" + integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1@~0.2.0: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assertion-error@^1.0.1: + 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" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async@~0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= + +async@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" + integrity sha1-+PwEyjoTeErenhZBr5hXjPvWR6k= + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +basic-auth@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" + integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== + dependencies: + safe-buffer "5.1.2" + +bcryptjs@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms= + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bluebird@^3.1.1, bluebird@^3.4.1: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +body-parser@1.19.0, body-parser@^1.18.2: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + +boxen@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" + integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^5.3.1" + chalk "^3.0.0" + cli-boxes "^2.2.0" + string-width "^4.1.0" + term-size "^2.1.0" + type-fest "^0.8.1" + widest-line "^3.1.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +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== + +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= + +buffer-writer@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" + integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== + +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase-keys@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" + integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== + dependencies: + camelcase "^5.3.1" + map-obj "^4.0.0" + quick-lru "^4.0.1" + +camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.0.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" + integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== + +chai-http@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/chai-http/-/chai-http-4.3.0.tgz#3c37c675c1f4fe685185a307e345de7599337c1a" + integrity sha512-zFTxlN7HLMv+7+SPXZdkd5wUlK+KxH6Q7bIEMiEx0FK3zuuMqL7cwICAQ0V1+yYRozBburYuxN1qZstgHpFZQg== + dependencies: + "@types/chai" "4" + "@types/superagent" "^3.8.3" + cookiejar "^2.1.1" + is-ip "^2.0.0" + methods "^1.1.2" + qs "^6.5.1" + superagent "^3.7.0" + +chai-uuid@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/chai-uuid/-/chai-uuid-1.0.6.tgz#353a3b817dd66aa2608a0660faf68593fb918c8b" + integrity sha1-NTo7gX3WaqJgigZg+vaFk/uRjIs= + +chai@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" + integrity sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc= + dependencies: + assertion-error "^1.0.1" + deep-eql "^0.1.3" + type-detect "^1.0.0" + +chalk@4.1.0, chalk@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@3.5.1, chokidar@^3.2.2: + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + 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.5.0" + optionalDependencies: + fsevents "~2.3.1" + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cli-boxes@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +co-mocha@^1.1.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/co-mocha/-/co-mocha-1.2.2.tgz#c4fdf24d37f43ca4da668b14542a96e9377479ab" + integrity sha512-ocdJRn3sxonOqpdjSU2VwTwWzjTSoatzsTqCWiC3eGvJFNs8ZNMlZwfgYolQCdfddMz4muiZl99KIV9gKoNvxg== + dependencies: + co "^4.0.0" + is-generator "^1.0.1" + +co@^4.0.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" + integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== + +colors@1.0.x: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= + +colors@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +compare-func@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3" + integrity sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA== + dependencies: + array-ify "^1.0.0" + dot-prop "^5.1.0" + +compare-versions@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" + integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== + +component-emitter@^1.2.0, component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +configstore@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" + integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== + dependencies: + dot-prop "^5.2.0" + graceful-fs "^4.1.2" + make-dir "^3.0.0" + unique-string "^2.0.0" + write-file-atomic "^3.0.0" + xdg-basedir "^4.0.0" + +confusing-browser-globals@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz#30d1e7f3d1b882b25ec4933d1d1adac353d20a59" + integrity sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA== + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +content-disposition@0.5.3: + 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: + 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== + +conventional-changelog-angular@^5.0.0: + version "5.0.12" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz#c979b8b921cbfe26402eb3da5bbfda02d865a2b9" + integrity sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw== + dependencies: + compare-func "^2.0.0" + q "^1.5.1" + +conventional-changelog-conventionalcommits@^4.3.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.5.0.tgz#a02e0b06d11d342fdc0f00c91d78265ed0bc0a62" + integrity sha512-buge9xDvjjOxJlyxUnar/+6i/aVEVGA7EEh4OafBCXPlLUQPGbRUBhBUveWRxzvR8TEjhKEP4BdepnpG2FSZXw== + dependencies: + compare-func "^2.0.0" + lodash "^4.17.15" + q "^1.5.1" + +conventional-commits-parser@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.1.tgz#ba44f0b3b6588da2ee9fd8da508ebff50d116ce2" + integrity sha512-OG9kQtmMZBJD/32NEw5IhN5+HnBqVjy03eC+I71I0oQRFA5rOgA4OtPOYG7mz1GkCfCNxn3gKIX8EiHJYuf1cA== + dependencies: + JSONStream "^1.0.4" + is-text-path "^1.0.1" + lodash "^4.17.15" + meow "^8.0.0" + split2 "^3.0.0" + through2 "^4.0.0" + trim-off-newlines "^1.0.0" + +cookie-parser@^1.4.4: + version "1.4.5" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.5.tgz#3e572d4b7c0c80f9c61daf604e4336831b5d1d49" + integrity sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw== + dependencies: + cookie "0.4.0" + cookie-signature "1.0.6" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== + +cookie@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +cookie@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +cookiejar@^2.1.0, cookiejar@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" + integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js@^3.6.1: + version "3.9.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.9.1.tgz#cec8de593db8eb2a85ffb0dbdeb312cb6e5460ae" + integrity sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg== + +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" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" + integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + +cycle@1.0.x: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" + integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI= + +dargs@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" + integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== + +database-cleaner@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/database-cleaner/-/database-cleaner-1.3.0.tgz#306c0015bd2eb968d08a6be6a24fe52dd91fd656" + integrity sha512-WZaUioWrKPkeBzWWKSuPalO48dIfsnuY+IEkYghUr2czRwFdw8LXdehE5+VH2GrQdSnmPnvYDZ1QGwNCMs8pPA== + +db-migrate-base@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/db-migrate-base/-/db-migrate-base-2.3.1.tgz#97029e230b344f00cf2e4475e2e6027f7b09994c" + integrity sha512-HewYQ3HPmy7NOWmhhMLg9TzN1StEtSqGL3w8IbBRCxEsJ+oM3bDUQ/z5fqpYKfIUK07mMXieCmZYwFpwWkSHDw== + dependencies: + bluebird "^3.1.1" + +db-migrate-pg@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/db-migrate-pg/-/db-migrate-pg-1.2.2.tgz#66436dbad0ba398c05851d200f768db6b2e5bc1a" + integrity sha512-+rgrhGNWC2SzcfweopyZqOQ1Igz1RVFMUZwUs6SviHpOUzFwb0NZWkG0pw1GaO+JxTxS7VJjckUWkOwZbVYVag== + dependencies: + bluebird "^3.1.1" + db-migrate-base "^2.3.0" + pg "^8.0.3" + semver "^5.0.3" + +db-migrate-shared@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/db-migrate-shared/-/db-migrate-shared-1.2.0.tgz#6125be1b3a5e661229fc75d50c85f6c3ffadbede" + integrity sha512-65k86bVeHaMxb2L0Gw3y5V+CgZSRwhVQMwDMydmw5MvIpHHwD6SmBciqIwHsZfzJ9yzV/yYhdRefRM6FV5/siw== + +db-migrate@^0.11.12: + version "0.11.12" + resolved "https://registry.yarnpkg.com/db-migrate/-/db-migrate-0.11.12.tgz#2798fc46da51fc2589497d462f3c6116802cfb6a" + integrity sha512-HUS8T5A3sKGCi+hz9XMKMwAKfU9sqhpDufW9nbVSRc5wxDO695uxA5lDe+If0OdvwwQOVxOnEZqkzAAxgyeFWg== + dependencies: + balanced-match "^1.0.0" + bluebird "^3.1.1" + db-migrate-shared "^1.2.0" + deep-extend "^0.6.0" + dotenv "^5.0.1" + final-fs "^1.6.0" + inflection "^1.10.0" + mkdirp "~0.5.0" + parse-database-url "~0.3.0" + prompt "^1.0.0" + rc "^1.2.8" + resolve "^1.1.6" + semver "^5.3.0" + tunnel-ssh "^4.0.0" + yargs "^15.3.1" + +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@4.3.1, debug@^4.0.1, debug@^4.1.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +debug@^3.1.0, debug@^3.2.6: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decamelize-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +deep-eql@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" + integrity sha1-71WKyrjeJSBs1xOQbXTlaTDrafI= + dependencies: + type-detect "0.1.1" + +deep-equal@~0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-0.2.2.tgz#84b745896f34c684e98f2ce0e42abaf43bba017d" + integrity sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +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== + +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" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" + integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +diff@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dot-prop@^5.1.0, dot-prop@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== + dependencies: + is-obj "^2.0.0" + +dotenv@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-5.0.1.tgz#a5317459bd3d79ab88cff6e44057a6a3fbb1fcef" + integrity sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow== + +dotenv@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" + integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: + version "1.18.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" + integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.2" + is-callable "^1.2.3" + is-negative-zero "^2.0.1" + is-regex "^1.1.2" + is-string "^1.0.5" + object-inspect "^1.9.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.0" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-goat@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" + integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== + +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@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +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= + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +eslint-config-airbnb-base@^14.2.0: + version "14.2.1" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz#8a2eb38455dc5a312550193b319cdaeef042cd1e" + integrity sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA== + dependencies: + confusing-browser-globals "^1.0.10" + object.assign "^4.1.2" + object.entries "^1.1.2" + +eslint-config-prettier@^6.13.0: + version "6.15.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz#7f93f6cb7d45a92f1537a70ecc06366e1ac6fed9" + integrity sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw== + dependencies: + get-stdin "^6.0.0" + +eslint-import-resolver-node@^0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" + integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== + dependencies: + debug "^2.6.9" + resolve "^1.13.1" + +eslint-module-utils@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" + integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== + dependencies: + debug "^2.6.9" + pkg-dir "^2.0.0" + +eslint-plugin-import@^2.22.1: + version "2.22.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" + integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== + dependencies: + array-includes "^3.1.1" + array.prototype.flat "^1.2.3" + contains-path "^0.1.0" + debug "^2.6.9" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.4" + eslint-module-utils "^2.6.0" + has "^1.0.3" + minimatch "^3.0.4" + object.values "^1.1.1" + read-pkg-up "^2.0.0" + resolve "^1.17.0" + tsconfig-paths "^3.9.0" + +eslint-plugin-prettier@^3.2.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.1.tgz#7079cfa2497078905011e6f82e8dd8453d1371b7" + integrity sha512-Rq3jkcFY8RYeQLgk2cCwuc0P7SEFwDravPhsJZOQ5N4YI4DSg50NyqJ/9gdZHzQlHf8MvafSesbNJCcP/FF6pQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" + integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== + +eslint@^7.11.0: + version "7.22.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.22.0.tgz#07ecc61052fec63661a2cab6bd507127c07adc6f" + integrity sha512-3VawOtjSJUQiiqac8MQc+w457iGLfuNGLFn8JmF051tTKbh5/x/0vlcEj8OgDCaw7Ysa2Jn8paGshV7x2abKXg== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash "^4.17.21" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.4" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +esm@^3.2.25: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +expect-runtime@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/expect-runtime/-/expect-runtime-0.7.0.tgz#793764cc8279075ae7da63a5da7e978638fa555a" + integrity sha512-7BZ5rAG04JL75dI9FNN2e2QO/gnfvo00rmLUhq0q+bX71Mb/Vd22fQggcr5B0+/nqK13IEUF2fnNOkV5SQs6WQ== + +expect@^26.4.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/expect/-/expect-26.6.2.tgz#c6b996bf26bf3fe18b67b2d0f51fc981ba934417" + integrity sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA== + dependencies: + "@jest/types" "^26.6.2" + ansi-styles "^4.0.0" + jest-get-type "^26.3.0" + jest-matcher-utils "^26.6.2" + jest-message-util "^26.6.2" + jest-regex-util "^26.0.0" + +express-async-handler@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/express-async-handler/-/express-async-handler-1.1.4.tgz#225a84908df63b35ae9df94b6f0f1af061266426" + integrity sha512-HdmbVF4V4w1q/iz++RV7bUxIeepTukWewiJGkoCKQMtvPF11MLTa7It9PRc/reysXXZSEyD4Pthchju+IUbMiQ== + +express-bearer-token@^2.1.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/express-bearer-token/-/express-bearer-token-2.4.0.tgz#f4d9d5a1e318953445e7f0d2bde00bb96d21c95a" + integrity sha512-2+kRZT2xo+pmmvSY7Ma5FzxTJpO3kGaPCEXPbAm3GaoZ/z6FE4K6L7cvs1AUZwY2xkk15PcQw7t4dWjsl5rdJw== + dependencies: + cookie "^0.3.1" + cookie-parser "^1.4.4" + +express-validator@^6.4.0: + version "6.10.0" + resolved "https://registry.yarnpkg.com/express-validator/-/express-validator-6.10.0.tgz#66f70f73d04fb55c227401c75fe3713879c9cb70" + integrity sha512-gDtepU94EpUzgFvKO/8JzjZ4uqIF4xHekjYtcNgFDiBK6Hob3MQhPU8s/c3NaWd1xi5e5nA0oVmOJ0b0ZBO36Q== + dependencies: + lodash "^4.17.20" + validator "^13.5.2" + +express@^4.16.2: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +eyes@0.1.x: + version "0.1.8" + resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" + integrity sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A= + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +final-fs@^1.6.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/final-fs/-/final-fs-1.6.1.tgz#d6dcd92ef6fe4fe8c07abd568c7135610ede3236" + integrity sha1-1tzZLvb+T+jAer1WjHE1YQ7eMjY= + dependencies: + node-fs "~0.1.5" + when "~2.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-up@5.0.0, find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-versions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-4.0.0.tgz#3c57e573bf97769b8cb8df16934b627915da4965" + integrity sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ== + dependencies: + semver-regex "^3.1.2" + +findup-sync@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +fined@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" + integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng== + dependencies: + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" + parse-filepath "^1.0.1" + +flagged-respawn@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" + integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +flatted@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" + integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= + dependencies: + for-in "^1.0.1" + +form-data@^2.3.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +formidable@^1.2.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" + integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q== + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + 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= + +fs-extra@^9.0.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +generate-password@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/generate-password/-/generate-password-1.6.0.tgz#9dff4fcca7f831e6832d464509910fab333d0323" + integrity sha512-YUJTQkApkLT/fru0QdYWP0lVZdPKhF5kXCP24sgI4gR/vFMJFopCj5t1+9FAKIYcML/nxzx2PMkA1ymO1FC+tQ== + +get-caller-file@^2.0.1, get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-stdin@8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" + integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== + +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getopts@2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.2.5.tgz#67a0fe471cacb9c687d817cab6450b96dde8313b" + integrity sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA== + +git-raw-commits@^2.0.0: + version "2.0.10" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.10.tgz#e2255ed9563b1c9c3ea6bd05806410290297bbc1" + integrity sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ== + dependencies: + dargs "^7.0.0" + lodash "^4.17.15" + meow "^8.0.0" + split2 "^3.0.0" + through2 "^4.0.0" + +glob-parent@^5.0.0, glob-parent@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@7.1.6, glob@^7.1.3: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + 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" + +global-dirs@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + +global-dirs@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d" + integrity sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ== + dependencies: + ini "1.3.7" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +globals@^12.1.0: + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== + dependencies: + type-fest "^0.8.1" + +globals@^13.6.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.7.0.tgz#aed3bcefd80ad3ec0f0be2cf0c895110c0591795" + integrity sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA== + dependencies: + type-fest "^0.20.2" + +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + +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== + +hard-rejection@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" + integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has-yarn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" + integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.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== + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + +hosted-git-info@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.0.2.tgz#5e425507eede4fea846b7262f0838456c4209961" + integrity sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg== + dependencies: + lru-cache "^6.0.0" + +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +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" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +husky@^4.3.5: + version "4.3.8" + resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.8.tgz#31144060be963fd6850e5cc8f019a1dfe194296d" + integrity sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow== + dependencies: + chalk "^4.0.0" + ci-info "^2.0.0" + compare-versions "^3.6.0" + cosmiconfig "^7.0.0" + find-versions "^4.0.0" + opencollective-postinstall "^2.0.2" + pkg-dir "^5.0.0" + please-upgrade-node "^3.2.0" + slash "^3.0.0" + which-pm-runs "^1.0.0" + +i@0.3.x: + version "0.3.6" + resolved "https://registry.yarnpkg.com/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d" + integrity sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0= + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflection@^1.10.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.12.0.tgz#a200935656d6f5f6bc4dc7502e1aecb703228416" + integrity sha1-ogCTVlbW9fa8TcdQLhrstwMihBY= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.3, 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== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" + integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== + +ini@^1.3.4, ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +ip-regex@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" + integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-bigint@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" + integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" + integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== + dependencies: + call-bind "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-core-module@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" + integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + dependencies: + has "^1.0.3" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-fullwidth-code-point@^3.0.0: + version "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@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-generator/-/is-generator-1.0.3.tgz#c14c21057ed36e328db80347966c693f886389f3" + integrity sha1-wUwhBX7TbjKNuANHlmxpP4hjifM= + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" + integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== + dependencies: + global-dirs "^2.0.1" + is-path-inside "^3.0.1" + +is-ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-2.0.0.tgz#68eea07e8a0a0a94c2d080dd674c731ab2a461ab" + integrity sha1-aO6gfooKCpTC0IDdZ0xzGrKkYas= + dependencies: + ip-regex "^2.0.0" + +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + +is-npm@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" + integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== + +is-number-object@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" + integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +is-path-inside@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-regex@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" + integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== + dependencies: + call-bind "^1.0.2" + has-symbols "^1.0.1" + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + +is-string@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" + integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" + integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + dependencies: + has-symbols "^1.0.1" + +is-text-path@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" + integrity sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4= + dependencies: + text-extensions "^1.0.0" + +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-yarn-global@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" + integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@0.1.x: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jest-diff@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" + integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== + dependencies: + chalk "^4.0.0" + diff-sequences "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-get-type@^26.3.0: + version "26.3.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" + integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== + +jest-matcher-utils@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz#8e6fd6e863c8b2d31ac6472eeb237bc595e53e7a" + integrity sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw== + dependencies: + chalk "^4.0.0" + jest-diff "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-message-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" + integrity sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@jest/types" "^26.6.2" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" + micromatch "^4.0.2" + pretty-format "^26.6.2" + slash "^3.0.0" + stack-utils "^2.0.2" + +jest-regex-util@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" + integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== + +joi@^17.2.1: + version "17.4.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.0.tgz#b5c2277c8519e016316e49ababd41a1908d9ef20" + integrity sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hapi/topo" "^5.0.0" + "@sideway/address" "^4.1.0" + "@sideway/formula" "^3.0.0" + "@sideway/pinpoint" "^2.0.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" + integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== + dependencies: + argparse "^2.0.1" + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + +jsonwebtoken@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.1.0.tgz#c6397cd2e5fd583d65c007a83dc7bb78e6982b83" + integrity sha1-xjl80uX9WD1lwAeoPce7eOaYK4M= + dependencies: + jws "^3.1.4" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.0.0" + xtend "^4.0.1" + +just-extend@^4.0.2: + version "4.1.1" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.1.tgz#158f1fdb01f128c411dc8b286a7b4837b3545282" + integrity sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA== + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.1.4: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +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" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +knex@^0.21.5: + version "0.21.19" + resolved "https://registry.yarnpkg.com/knex/-/knex-0.21.19.tgz#df504a184eb29e286245839db0867e3ca161af00" + integrity sha512-6etvrq9XI1Ck6mEc/XiXFGVpD1Lmj6v9XWojqZgEbOvyMbW7XRvgZ99yIhN/kaBH+43FEy3xv/AcbRaH+1pJtw== + dependencies: + colorette "1.2.1" + commander "^6.2.0" + debug "4.3.1" + esm "^3.2.25" + getopts "2.2.5" + interpret "^2.2.0" + liftoff "3.1.0" + lodash "^4.17.20" + pg-connection-string "2.4.0" + tarn "^3.0.1" + tildify "2.0.0" + v8flags "^3.2.0" + +latest-version@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" + integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== + dependencies: + package-json "^6.3.0" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +liftoff@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" + integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog== + dependencies: + extend "^3.0.0" + findup-sync "^3.0.0" + fined "^1.0.1" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" + rechoir "^0.6.2" + resolve "^1.1.7" + +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.defaults@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= + +lodash@^4.14.2, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-symbols@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" + integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== + dependencies: + chalk "^4.0.0" + +loglevel@^1.6.8: + version "1.7.1" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" + integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru_map@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" + integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= + +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-iterator@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" + integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== + dependencies: + kind-of "^6.0.2" + +map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-obj@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.2.0.tgz#0e8bc823e2aaca8a0942567d12ed14f389eec153" + integrity sha512-NAq0fCmZYGz9UFEQyndp7sisrow4GroyGeKluyKC/chuITZsPyOyC1UJZPJlVFImhXdROIP5xqouRLThT3BbpQ== + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +meow@^8.0.0: + version "8.1.2" + resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" + integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q== + dependencies: + "@types/minimist" "^1.2.0" + camelcase-keys "^6.2.2" + decamelize-keys "^1.1.0" + hard-rejection "^2.1.0" + minimist-options "4.1.0" + normalize-package-data "^3.0.0" + read-pkg-up "^7.0.1" + redent "^3.0.0" + trim-newlines "^3.0.0" + type-fest "^0.18.0" + yargs-parser "^20.2.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^3.0.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +mime-db@1.46.0: + version "1.46.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee" + integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== + +mime-types@^2.1.12, mime-types@~2.1.24: + version "2.1.29" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2" + integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== + dependencies: + mime-db "1.46.0" + +mime@1.6.0, mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +min-indent@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" + integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== + +minimatch@3.0.4, 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== + dependencies: + brace-expansion "^1.1.7" + +minimist-options@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" + integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + kind-of "^6.0.3" + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.x.x, mkdirp@~0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mocha@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.3.2.tgz#53406f195fa86fbdebe71f8b1c6fb23221d69fcc" + integrity sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.1" + debug "4.3.1" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.1.6" + growl "1.10.5" + he "1.2.0" + js-yaml "4.0.0" + log-symbols "4.0.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.1.20" + serialize-javascript "5.0.1" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + wide-align "1.1.3" + workerpool "6.1.0" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +mock-knex@^0.4.9: + version "0.4.9" + resolved "https://registry.yarnpkg.com/mock-knex/-/mock-knex-0.4.9.tgz#af831d376500483d6499469eb847842490af04c3" + integrity sha512-w8BZXdKeNtPxcXu/cnJVCv+/e+Nxs8sfDulxfV/MK2+NErxbv/NYkQA7Kr15TNYA8Q51WyFTwD4bNQB9/YWotw== + dependencies: + bluebird "^3.4.1" + lodash "^4.14.2" + semver "^5.3.0" + +"mongodb-uri@>= 0.9.7": + version "0.9.7" + resolved "https://registry.yarnpkg.com/mongodb-uri/-/mongodb-uri-0.9.7.tgz#0f771ad16f483ae65f4287969428e9fbc4aa6181" + integrity sha1-D3ca0W9IOuZfQoeWlCjp+8SqYYE= + +morgan@^1.9.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" + integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== + dependencies: + basic-auth "~2.0.1" + debug "2.6.9" + depd "~2.0.0" + on-finished "~2.3.0" + on-headers "~1.0.2" + +ms@2.0.0: + version "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.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.0.0, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mute-stream@~0.0.4: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nanoid@3.1.20: + version "3.1.20" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" + integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +ncp@1.0.x: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246" + integrity sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY= + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +nise@^4.0.4: + version "4.1.0" + resolved "https://registry.yarnpkg.com/nise/-/nise-4.1.0.tgz#8fb75a26e90b99202fa1e63f448f58efbcdedaf6" + integrity sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@sinonjs/fake-timers" "^6.0.0" + "@sinonjs/text-encoding" "^0.7.1" + just-extend "^4.0.2" + path-to-regexp "^1.7.0" + +node-fs@~0.1.5: + version "0.1.7" + resolved "https://registry.yarnpkg.com/node-fs/-/node-fs-0.1.7.tgz#32323cccb46c9fbf0fc11812d45021cc31d325bb" + integrity sha1-MjI8zLRsn78PwRgS1FAhzDHTJbs= + +nodemon@^2.0.4: + version "2.0.7" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.7.tgz#6f030a0a0ebe3ea1ba2a38f71bf9bab4841ced32" + integrity sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA== + dependencies: + chokidar "^3.2.2" + debug "^3.2.6" + ignore-by-default "^1.0.1" + minimatch "^3.0.4" + pstree.remy "^1.1.7" + semver "^5.7.1" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.3" + update-notifier "^4.1.0" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-package-data@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.2.tgz#cae5c410ae2434f9a6c1baa65d5bc3b9366c8699" + integrity sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg== + dependencies: + hosted-git-info "^4.0.1" + resolve "^1.20.0" + semver "^7.3.4" + validate-npm-package-license "^3.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" + integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" + integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8= + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + +object.entries@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.3.tgz#c601c7f168b62374541a07ddbd3e2d5e4f7711a6" + integrity sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.1" + has "^1.0.3" + +object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc= + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +object.pick@^1.2.0, object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.values@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" + integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + has "^1.0.3" + +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= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +opencollective-postinstall@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" + integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +package-json@^6.3.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== + dependencies: + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" + +packet-reader@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" + integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-database-url@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/parse-database-url/-/parse-database-url-0.3.0.tgz#369666321e927c9ade63cdfc1aaaf6fb37453d0d" + integrity sha1-NpZmMh6SfJreY838Gqr2+zdFPQ0= + dependencies: + mongodb-uri ">= 0.9.7" + +parse-filepath@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +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== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= + dependencies: + path-root-regex "^0.1.0" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-to-regexp@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pg-connection-string@2.4.0, pg-connection-string@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.4.0.tgz#c979922eb47832999a204da5dbe1ebf2341b6a10" + integrity sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ== + +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== + +pg-pool@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.2.2.tgz#a560e433443ed4ad946b84d774b3f22452694dff" + integrity sha512-ORJoFxAlmmros8igi608iVEbQNNZlp89diFVx6yV5v+ehmpMY9sK6QgpmgoXbmkNaBAx8cOOZh9g80kJv1ooyA== + +pg-protocol@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.4.0.tgz#43a71a92f6fe3ac559952555aa3335c8cb4908be" + integrity sha512-El+aXWcwG/8wuFICMQjM5ZSAm6OWiJicFdNYo+VY3QP+8vI4SvLIWVe51PppTzMhikUJR+PsyIFKqfdXPz/yxA== + +pg-types@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== + dependencies: + pg-int8 "1.0.1" + postgres-array "~2.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.4" + postgres-interval "^1.1.0" + +pg@^8.0.3, pg@^8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.5.1.tgz#34dcb15f6db4a29c702bf5031ef2e1e25a06a120" + integrity sha512-9wm3yX9lCfjvA98ybCyw2pADUivyNWT/yIP4ZcDVpMN0og70BUWYEGXPCTAQdGTAqnytfRADb7NERrY1qxhIqw== + dependencies: + buffer-writer "2.0.0" + packet-reader "1.0.0" + pg-connection-string "^2.4.0" + pg-pool "^3.2.2" + pg-protocol "^1.4.0" + pg-types "^2.1.0" + pgpass "1.x" + +pgpass@1.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.4.tgz#85eb93a83800b20f8057a2b029bf05abaf94ea9c" + integrity sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w== + dependencies: + split2 "^3.1.1" + +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + +please-upgrade-node@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" + integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== + dependencies: + semver-compare "^1.0.0" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postgres-array@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU= + +postgres-date@~1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== + +postgres-interval@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== + dependencies: + xtend "^4.0.0" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.1.2: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" + integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== + +pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== + dependencies: + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +prompt@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.1.0.tgz#7ae829c6d39bbc6f9b1927f9861e9ac074744167" + integrity sha512-ec1vUPXCplDBDUVD8uPa3XGA+OzLrO40Vxv3F1uxoiZGkZhdctlK2JotcHq5X6ExjocDOGwGdCSXloGNyU5L1Q== + dependencies: + colors "^1.1.2" + read "1.0.x" + revalidator "0.1.x" + utile "0.3.x" + winston "2.x" + +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.9.1" + +pstree.remy@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +pupa@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== + dependencies: + escape-goat "^2.0.0" + +q@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +qs@^6.5.1: + version "6.10.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" + integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg== + dependencies: + side-channel "^1.0.4" + +quick-lru@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" + integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +read@1.0.x: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= + dependencies: + mute-stream "~0.0.4" + +readable-stream@3, readable-stream@^3.0.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@^2.3.5: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpp@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" + integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + +registry-auth-token@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" + integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== + dependencies: + rc "^1.2.8" + +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + dependencies: + rc "^1.2.8" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@5.0.0, resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-global@1.0.0, resolve-global@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-global/-/resolve-global-1.0.0.tgz#a2a79df4af2ca3f49bf77ef9ddacd322dad19255" + integrity sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw== + dependencies: + global-dirs "^0.1.1" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +revalidator@0.1.x: + version "0.1.8" + resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" + integrity sha1-/s5hv6DBtSoga9axgZgYS91SOjs= + +rimraf@2.x.x: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +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.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + +semver-diff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" + integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== + dependencies: + semver "^6.3.0" + +semver-regex@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.2.tgz#34b4c0d361eef262e07199dbef316d0f2ab11807" + integrity sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA== + +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.7.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + +semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.2.1, semver@^7.3.4: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serialize-javascript@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== + dependencies: + randombytes "^2.1.0" + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +sinon-chai@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-2.14.0.tgz#da7dd4cc83cd6a260b67cca0f7a9fdae26a1205d" + integrity sha512-9stIF1utB0ywNHNT7RgiXbdmen8QDCRsrTjw+G9TgKt1Yexjiv8TOWZ6WHsTPz57Yky3DIswZvEqX8fpuHNDtQ== + +sinon@^9.0.3: + version "9.2.4" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-9.2.4.tgz#e55af4d3b174a4443a8762fa8421c2976683752b" + integrity sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg== + dependencies: + "@sinonjs/commons" "^1.8.1" + "@sinonjs/fake-timers" "^6.0.1" + "@sinonjs/samsam" "^5.3.1" + diff "^4.0.2" + nise "^4.0.4" + supports-color "^7.1.0" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" + integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +split2@^3.0.0, split2@^3.1.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" + integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== + dependencies: + readable-stream "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +ssh2-streams@~0.1.15: + version "0.1.20" + resolved "https://registry.yarnpkg.com/ssh2-streams/-/ssh2-streams-0.1.20.tgz#51118d154555df5469ee1f67e0cf1e7e8a2c0e3a" + integrity sha1-URGNFUVV31Rp7h9n4M8efoosDjo= + dependencies: + asn1 "~0.2.0" + semver "^5.1.0" + streamsearch "~0.1.2" + +ssh2@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-0.5.4.tgz#1bf6b6b28c96eaef267f4d6c46a5a2517a599e27" + integrity sha1-G/a2soyW6u8mf01sRqWiUXpZnic= + dependencies: + ssh2-streams "~0.1.15" + +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= + +stack-utils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" + integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw== + dependencies: + escape-string-regexp "^2.0.0" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +streamsearch@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +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= + +superagent@^3.7.0, superagent@^3.8.3: + version "3.8.3" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.3.tgz#460ea0dbdb7d5b11bc4f78deba565f86a178e128" + integrity sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA== + dependencies: + component-emitter "^1.2.0" + cookiejar "^2.1.0" + debug "^3.1.0" + extend "^3.0.0" + form-data "^2.3.1" + formidable "^1.2.0" + methods "^1.1.1" + mime "^1.4.1" + qs "^6.5.1" + readable-stream "^2.3.5" + +supertest@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-4.0.2.tgz#c2234dbdd6dc79b6f15b99c8d6577b90e4ce3f36" + integrity sha512-1BAbvrOZsGA3YTCWqbmh14L0YEq0EGICX/nBnfkfVJn7SrxQV1I3pMYjSzG9y/7ZU2V9dWqyqk2POwxlb09duQ== + dependencies: + methods "^1.1.2" + superagent "^3.8.3" + +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +table@^6.0.4: + version "6.0.7" + resolved "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34" + integrity sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g== + dependencies: + ajv "^7.0.2" + lodash "^4.17.20" + slice-ansi "^4.0.0" + string-width "^4.2.0" + +tarn@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.1.tgz#ebac2c6dbc6977d34d4526e0a7814200386a8aec" + integrity sha512-6usSlV9KyHsspvwu2duKH+FMUhqJnAh6J5J/4MITl8s94iSUQTLkJggdiewKv4RyARQccnigV48Z+khiuVZDJw== + +term-size@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" + integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== + +text-extensions@^1.0.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" + integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through2@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" + integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== + dependencies: + readable-stream "3" + +"through@>=2.2.7 <3": + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +tildify@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tildify/-/tildify-2.0.0.tgz#f205f3674d677ce698b7067a99e949ce03b4754a" + integrity sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw== + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + +trim-newlines@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30" + integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA== + +trim-off-newlines@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= + +tsconfig-paths@^3.9.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" + integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.0" + strip-bom "^3.0.0" + +tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tunnel-ssh@^4.0.0: + version "4.1.4" + resolved "https://registry.yarnpkg.com/tunnel-ssh/-/tunnel-ssh-4.1.4.tgz#b301f7733c73dcea1616466b9c87b607f4958b45" + integrity sha512-CjBqboGvAbM7iXSX2F95kzoI+c2J81YkrHbyyo4SWNKCzU6w5LfEvXBCHu6PPriYaNvfhMKzD8bFf5Vl14YTtg== + dependencies: + debug "2.6.9" + lodash.defaults "^4.1.0" + ssh2 "0.5.4" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-detect@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" + integrity sha1-C6XsKohWQORw6k6FBZcZANrFiCI= + +type-detect@4.0.8, type-detect@^4.0.8: + 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-detect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" + integrity sha1-diIXzAbbJY7EiQihKY6LlRIejqI= + +type-fest@^0.18.0: + version "0.18.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" + integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.8.1: + version "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.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +unbox-primitive@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= + +undefsafe@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" + integrity sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A== + dependencies: + debug "^2.2.0" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +update-notifier@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3" + integrity sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A== + dependencies: + boxen "^4.2.0" + chalk "^3.0.0" + configstore "^5.0.1" + has-yarn "^2.1.0" + import-lazy "^2.1.0" + is-ci "^2.0.0" + is-installed-globally "^0.3.1" + is-npm "^4.0.0" + is-yarn-global "^0.3.0" + latest-version "^5.0.0" + pupa "^2.0.1" + semver-diff "^3.1.1" + xdg-basedir "^4.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +utile@0.3.x: + version "0.3.0" + resolved "https://registry.yarnpkg.com/utile/-/utile-0.3.0.tgz#1352c340eb820e4d8ddba039a4fbfaa32ed4ef3a" + integrity sha1-E1LDQOuCDk2N26A5pPv6oy7U7zo= + dependencies: + async "~0.9.0" + deep-equal "~0.2.1" + i "0.3.x" + mkdirp "0.x.x" + ncp "1.0.x" + rimraf "2.x.x" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^8.2.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +v8flags@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" + integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== + dependencies: + homedir-polyfill "^1.0.1" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +validator@^13.5.2: + version "13.5.2" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.5.2.tgz#c97ae63ed4224999fb6f42c91eaca9567fe69a46" + integrity sha512-mD45p0rvHVBlY2Zuy3F3ESIe1h5X58GPfAtslBjY7EtTqGquZTj+VX/J4RnHWN8FKq0C9WRVt1oWAcytWRuYLQ== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +when@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/when/-/when-2.0.1.tgz#8d872fe15e68424c91b4b724e848e0807dab6642" + integrity sha1-jYcv4V5oQkyRtLck6EjggH2rZkI= + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + +which@2.0.2, which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +which@^1.2.14: + 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.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + +winston@2.x: + version "2.4.5" + resolved "https://registry.yarnpkg.com/winston/-/winston-2.4.5.tgz#f2e431d56154c4ea765545fc1003bd340c95b59a" + integrity sha512-TWoamHt5yYvsMarGlGEQE59SbJHqGsZV8/lwC+iCcGeAe0vUaOh+Lv6SYM17ouzC/a/LB1/hz/7sxFBtlu1l4A== + dependencies: + async "~1.0.0" + colors "1.0.x" + cycle "1.0.x" + eyes "0.1.x" + isstream "0.1.x" + stack-trace "0.0.x" + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +workerpool@6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" + integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +xdg-basedir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + +xtend@^4.0.0, xtend@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== + +y18n@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" + integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^20.2.2, yargs-parser@^20.2.3: + version "20.2.7" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" + integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^15.1.0, yargs@^15.3.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.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 "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==