diff --git a/infrastructure/local/.env b/infrastructure/local/.env index 9c7c5f7251..247f06a6f3 100644 --- a/infrastructure/local/.env +++ b/infrastructure/local/.env @@ -1,7 +1,5 @@ -MERCURY_MEDIATOR_VERSION=0.3.0 -IRIS_SERVICE_VERSION=0.1.0 -PRISM_AGENT_VERSION=1.6.0 -PRISM_NODE_VERSION=v2.1.3 +PRISM_AGENT_VERSION=1.9.2 +PRISM_NODE_VERSION=2.2.1 PORT=80 NETWORK=prism VAULT_DEV_ROOT_TOKEN_ID=root diff --git a/tests/performance-tests/atala-performance-tests-k6/package.json b/tests/performance-tests/atala-performance-tests-k6/package.json index e5c1a2b3f8..b0a9fa45d5 100644 --- a/tests/performance-tests/atala-performance-tests-k6/package.json +++ b/tests/performance-tests/atala-performance-tests-k6/package.json @@ -25,6 +25,7 @@ "start": "webpack" }, "dependencies": { - "@input-output-hk/prism-typescript-client": "0.1.0" + "@input-output-hk/prism-typescript-client": "1.9.2", + "uuid": "^9.0.0" } } diff --git a/tests/performance-tests/atala-performance-tests-k6/src/actors/Holder.ts b/tests/performance-tests/atala-performance-tests-k6/src/actors/Holder.ts index cd83663280..e574af988d 100644 --- a/tests/performance-tests/atala-performance-tests-k6/src/actors/Holder.ts +++ b/tests/performance-tests/atala-performance-tests-k6/src/actors/Holder.ts @@ -88,8 +88,8 @@ export class Holder extends Actor { /** * Waits for a credential offer and accepts it. */ - waitAndAcceptCredentialOffer() { - this.credential = this.credentialsService.waitForCredentialOffer(); + waitAndAcceptCredentialOffer(thid: string) { + this.credential = this.credentialsService.waitForCredentialOffer(thid); this.credentialsService.acceptCredentialOffer(this.credential, this.did!); this.credentialsService.waitForCredentialState(this.credential, "RequestSent"); } @@ -104,8 +104,8 @@ export class Holder extends Actor { /** * Waits for a proof request, accepts it, and waits for the presentation to be sent. */ - waitAndAcceptProofRequest() { - const presentation = this.proofsService.waitForProof(); + waitAndAcceptProofRequest(thid: string) { + const presentation = this.proofsService.waitForProof(thid); this.proofsService.acceptProofRequest(presentation, this.credential!.recordId); this.proofsService.waitForPresentationState(presentation.presentationId, "PresentationSent"); } diff --git a/tests/performance-tests/atala-performance-tests-k6/src/actors/Issuer.ts b/tests/performance-tests/atala-performance-tests-k6/src/actors/Issuer.ts index b65422be44..fa377774fb 100644 --- a/tests/performance-tests/atala-performance-tests-k6/src/actors/Issuer.ts +++ b/tests/performance-tests/atala-performance-tests-k6/src/actors/Issuer.ts @@ -1,4 +1,4 @@ -import { Connection, IssueCredentialRecord } from "@input-output-hk/prism-typescript-client"; +import { Connection, CredentialSchemaResponse, IssueCredentialRecord } from "@input-output-hk/prism-typescript-client"; import { Actor } from "./Actor"; import { ISSUER_AGENT_API_KEY, ISSUER_AGENT_URL } from "../common/Config"; @@ -19,6 +19,11 @@ export class Issuer extends Actor { */ credential: IssueCredentialRecord | undefined; + /** + * The schema for issued credential. + */ + schema: CredentialSchemaResponse | undefined; + /** * The DID template used to create a DID for Issuer. * assertionMethod is the only purpose for the public key required for Issuer. @@ -74,11 +79,15 @@ export class Issuer extends Actor { this.didService.waitForDidState(this.longFormDid!, "PUBLISHED"); } + createCredentialSchema() { + this.schema = this.credentialsService.createCredentialSchema(this.did!); + } + /** * Creates a credential offer for the holder. */ createCredentialOffer() { - this.credential = this.credentialsService.createCredentialOffer(this.did!, this.connectionWithHolder!); + this.credential = this.credentialsService.createCredentialOffer(this.did!, this.connectionWithHolder!, this.schema!); } /** diff --git a/tests/performance-tests/atala-performance-tests-k6/src/actors/Verifier.ts b/tests/performance-tests/atala-performance-tests-k6/src/actors/Verifier.ts index 6129b441d9..7c051719d1 100644 --- a/tests/performance-tests/atala-performance-tests-k6/src/actors/Verifier.ts +++ b/tests/performance-tests/atala-performance-tests-k6/src/actors/Verifier.ts @@ -1,4 +1,4 @@ -import { Connection } from "@input-output-hk/prism-typescript-client"; +import { Connection, PresentationStatus } from "@input-output-hk/prism-typescript-client"; import { Actor } from "./Actor"; import { VERIFIER_AGENT_API_KEY, VERIFIER_AGENT_URL } from "../common/Config"; @@ -12,7 +12,7 @@ export class Verifier extends Actor { /** * Presentation ID. */ - presentationId: string | undefined; + presentation: PresentationStatus | undefined; /** * Creates a new instance of Verifier. @@ -42,13 +42,14 @@ export class Verifier extends Actor { * Requests proof from the holder. */ requestProof() { - this.presentationId = this.proofsService.requestProof(this.connectionWithHolder!); + let presentationId = this.proofsService.requestProof(this.connectionWithHolder!); + this.presentation = this.proofsService.getPresentation(presentationId); } /** * Acknowledges the proof received from the holder. */ acknowledgeProof() { - this.proofsService.waitForPresentationState(this.presentationId!, "PresentationVerified"); + this.proofsService.waitForPresentationState(this.presentation!.presentationId!, "PresentationVerified"); } } diff --git a/tests/performance-tests/atala-performance-tests-k6/src/common/CredentialsService.ts b/tests/performance-tests/atala-performance-tests-k6/src/common/CredentialsService.ts index 6f1ee9f81a..8961b64b9a 100644 --- a/tests/performance-tests/atala-performance-tests-k6/src/common/CredentialsService.ts +++ b/tests/performance-tests/atala-performance-tests-k6/src/common/CredentialsService.ts @@ -1,8 +1,8 @@ import { sleep } from "k6"; import { HttpService } from "./HttpService"; -import { WAITING_LOOP_MAX_ITERATIONS, WAITING_LOOP_PAUSE_INTERVAL } from "./Config"; -import { IssueCredentialRecord, Connection } from "@input-output-hk/prism-typescript-client"; -import vu from "k6/execution"; +import { ISSUER_AGENT_URL, WAITING_LOOP_MAX_ITERATIONS, WAITING_LOOP_PAUSE_INTERVAL } from "./Config"; +import { IssueCredentialRecord, Connection, CredentialSchemaResponse } from "@input-output-hk/prism-typescript-client"; +import {v4 as uuidv4} from 'uuid'; /** * A service class for managing credentials in the application. @@ -16,9 +16,16 @@ export class CredentialsService extends HttpService { * @param {Connection} connection - The connection object. * @returns {IssueCredentialRecord} The created credential offer record. */ - createCredentialOffer(issuingDid: string, connection: Connection): IssueCredentialRecord { + createCredentialOffer(issuingDid: string, connection: Connection, schema: CredentialSchemaResponse): IssueCredentialRecord { const payload = `{ - "claims": { "offerId": "${vu.vu.idInInstance}-${vu.vu.idInTest}-${vu.vu.iterationInScenario}" }, + "claims": { + "emailAddress": "${uuidv4()}-@atala.io", + "familyName": "Test", + "dateOfIssuance": "${new Date()}", + "drivingLicenseID": "Test", + "drivingClass": 1 + }, + "schemaId": "${ISSUER_AGENT_URL.replace("localhost", "host.docker.internal")}/schema-registry/schemas/${schema.guid}", "issuingDID": "${issuingDid}", "connectionId": "${connection.connectionId}", "automaticIssuance": false @@ -27,6 +34,60 @@ export class CredentialsService extends HttpService { return res.json() as unknown as IssueCredentialRecord; } + createCredentialSchema(issuingDid: string): CredentialSchemaResponse { + const payload = ` + { + "name": "${uuidv4()}}", + "version": "1.0.0", + "description": "Simple credential schema for the driving licence verifiable credential.", + "type": "https://w3c-ccg.github.io/vc-json-schemas/schema/2.0/schema.json", + "schema": { + "$id": "https://example.com/driving-license-1.0", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "Driving License", + "type": "object", + "properties": { + "emailAddress": { + "type": "string", + "format": "email" + }, + "givenName": { + "type": "string" + }, + "familyName": { + "type": "string" + }, + "dateOfIssuance": { + "type": "string" + }, + "drivingLicenseID": { + "type": "string" + }, + "drivingClass": { + "type": "integer" + } + }, + "required": [ + "emailAddress", + "familyName", + "dateOfIssuance", + "drivingLicenseID", + "drivingClass" + ], + "additionalProperties": false + }, + "tags": [ + "driving", + "licence", + "id" + ], + "author": "${issuingDid}" + } + ` + const res = this.post("schema-registry/schemas", payload); + return res.json() as unknown as CredentialSchemaResponse; + } + /** * Retrieves a specific credential record by ID. * @param {IssueCredentialRecord} record - The credential record. @@ -41,8 +102,8 @@ export class CredentialsService extends HttpService { * Retrieves all credential records. * @returns {IssueCredentialRecord[]} An array of credential records. */ - getCredentialRecords(): IssueCredentialRecord[] { - const res = this.get("issue-credentials/records"); + getCredentialRecords(thid: string): IssueCredentialRecord[] { + const res = this.get(`issue-credentials/records?thid=${thid}`); return res.json("contents") as unknown as IssueCredentialRecord[]; } @@ -73,21 +134,21 @@ export class CredentialsService extends HttpService { * @returns {IssueCredentialRecord} The received credential offer record. * @throws {Error} If the credential offer is not received within the maximum iterations. */ - waitForCredentialOffer(): IssueCredentialRecord { + waitForCredentialOffer(thid: string): IssueCredentialRecord { let iterations = 0; let record: IssueCredentialRecord | undefined; do { - console.log(`${vu.vu.idInInstance}-${vu.vu.idInTest}-${vu.vu.iterationInScenario}`) - record = this.getCredentialRecords().find( - r => r.claims["offerId"] === `${vu.vu.idInInstance}-${vu.vu.idInTest}-${vu.vu.iterationInScenario}` - && r.protocolState === "OfferReceived"); + // console.log(`Waiting for credential offer with thid=${thid}`) + record = this.getCredentialRecords(thid).find( + r => r.thid === thid && r.protocolState === "OfferReceived" + ); if (record) { return record; } sleep(WAITING_LOOP_PAUSE_INTERVAL); iterations++; } while (iterations < WAITING_LOOP_MAX_ITERATIONS); - throw new Error(`Record with offerId=${vu.vu.idInTest} not achieved during the waiting loop`); + throw new Error(`Record with thid=${thid} not achieved during the waiting loop`); } /** @@ -102,14 +163,12 @@ export class CredentialsService extends HttpService { do { const response = this.getCredentialRecord(credentialRecord); currentState = response.protocolState; - console.log(`Credential state: ${currentState}`) sleep(WAITING_LOOP_PAUSE_INTERVAL); iterations++; } while (currentState !== state && iterations < WAITING_LOOP_MAX_ITERATIONS); if (currentState !== state) { throw new Error(`Credential is not ${state} after the waiting loop`); } - if (__ENV.DEBUG) console.log(`Credential state achieved: ${currentState}`); } } diff --git a/tests/performance-tests/atala-performance-tests-k6/src/common/ProofsService.ts b/tests/performance-tests/atala-performance-tests-k6/src/common/ProofsService.ts index 3ee0652129..b52c723a25 100644 --- a/tests/performance-tests/atala-performance-tests-k6/src/common/ProofsService.ts +++ b/tests/performance-tests/atala-performance-tests-k6/src/common/ProofsService.ts @@ -68,8 +68,8 @@ export class ProofsService extends HttpService { * Retrieves all presentations. * @returns {PresentationStatus[]} An array of presentation status objects. */ - getPresentations(): PresentationStatus[] { - const res = this.get(`present-proof/presentations`); + getPresentations(thid: string): PresentationStatus[] { + const res = this.get(`present-proof/presentations?thid=${thid}`); return res.json("contents") as unknown as PresentationStatus[]; } @@ -78,13 +78,13 @@ export class ProofsService extends HttpService { * @returns {PresentationStatus} The received presentation status object. * @throws {Error} If the proof request is not received within the maximum iterations. */ - waitForProof(): PresentationStatus { + waitForProof(thid: string): PresentationStatus { let iterations = 0; let presentation: PresentationStatus | undefined; do { - // TODO: add correct filtering here when the API is fixed - // see ATL-4665 - presentation = this.getPresentations().find(r => r.status === "RequestReceived"); + presentation = this.getPresentations(thid).find( + r => r.thid === thid && r.status === "RequestReceived" + ); if (presentation) { return presentation; } @@ -105,11 +105,10 @@ export class ProofsService extends HttpService { let state: string; do { state = this.getPresentation(presentationId).status; - if (__ENV.DEBUG) console.log(`Presentation state: ${state}, required: ${requiredState}`); sleep(WAITING_LOOP_PAUSE_INTERVAL); iterations++; } while (state !== requiredState && iterations < WAITING_LOOP_MAX_ITERATIONS); - if (state != requiredState) { + if (state !== requiredState) { throw new Error(`Presentation state is ${state}, required ${requiredState}`); } } diff --git a/tests/performance-tests/atala-performance-tests-k6/src/tests/credentials/credential-schema-test.ts b/tests/performance-tests/atala-performance-tests-k6/src/tests/credentials/credential-schema-test.ts new file mode 100644 index 0000000000..095eee806f --- /dev/null +++ b/tests/performance-tests/atala-performance-tests-k6/src/tests/credentials/credential-schema-test.ts @@ -0,0 +1,43 @@ +import { group } from 'k6'; +import { Options } from 'k6/options'; +import { Issuer } from '../../actors'; + +export let options: Options = { + scenarios: { + smoke: { + executor: 'constant-vus', + vus: 3, + duration: "1s", + }, + }, + thresholds: { + 'http_req_duration{group:::Issuer creates credential schema}': ['max >= 0'], + 'http_reqs{group:::Issuer creates credential schema}': ['count >= 0'], + 'group_duration{group:::Issuer creates credential schema}': ['max >= 0'], + checks: ['rate==1'], + http_req_duration: ['p(95)<=100'], + }, +}; + +export const issuer = new Issuer(); + +export function setup() { + group('Issuer publishes DID', function () { + issuer.createUnpublishedDid(); + issuer.publishDid(); + }); + + return { + issuerDid: issuer.did, + }; +} + +export default (data: { issuerDid: string; }) => { + + // This is the only way to pass data from setup to default + issuer.did = data.issuerDid; + + group('Issuer creates credential schema', function () { + issuer.createCredentialSchema(); + }); +}; diff --git a/tests/performance-tests/atala-performance-tests-k6/src/tests/flows/issuance-flow-test.ts b/tests/performance-tests/atala-performance-tests-k6/src/tests/flows/issuance-flow-test.ts index 20abb5694b..c4f52a0094 100644 --- a/tests/performance-tests/atala-performance-tests-k6/src/tests/flows/issuance-flow-test.ts +++ b/tests/performance-tests/atala-performance-tests-k6/src/tests/flows/issuance-flow-test.ts @@ -1,19 +1,24 @@ import { group } from 'k6'; import { Options } from 'k6/options'; import {issuer, holder} from '../common'; +import { CredentialSchemaResponse } from '@input-output-hk/prism-typescript-client'; export let options: Options = { - stages: [ - { duration: '1s', target: 1 }, - ], - // thresholds: { - // http_req_failed: [{ - // threshold: 'rate<=0.05', - // abortOnFail: true, - // }], - // http_req_duration: ['p(95)<=1000'], - // checks: ['rate>=0.99'], - // }, + scenarios: { + smoke: { + executor: 'constant-vus', + vus: 5, + duration: "3m", + }, + }, + thresholds: { + http_req_failed: [{ + threshold: 'rate==0', + abortOnFail: true, + }], + http_req_duration: ['p(95)<=500'], + checks: ['rate==1'], + }, }; // This is setup code. It runs once at the beginning of the test, regardless of the number of VUs. @@ -24,17 +29,22 @@ export function setup() { issuer.publishDid(); }); + group('Issuer creates credential schema', function () { + issuer.createCredentialSchema(); + }); + group('Holder creates unpublished DID', function () { holder.createUnpublishedDid(); }); - return { issuerDid: issuer.did, holderDid: holder.did }; + return { issuerDid: issuer.did, holderDid: holder.did, issuerSchema: issuer.schema }; } -export default (data: { issuerDid: string; holderDid: string; }) => { +export default (data: { issuerDid: string; holderDid: string; issuerSchema: CredentialSchemaResponse}) => { // This is the only way to pass data from setup to default issuer.did = data.issuerDid; + issuer.schema = data.issuerSchema; holder.did = data.holderDid; group('Issuer connects with Holder', function () { @@ -50,7 +60,7 @@ export default (data: { issuerDid: string; holderDid: string; }) => { }); group('Holder achieves and accepts credential offer from Issuer', function () { - holder.waitAndAcceptCredentialOffer(); + holder.waitAndAcceptCredentialOffer(issuer.credential!.thid); }); group('Issuer issues credential to Holder', function () { diff --git a/tests/performance-tests/atala-performance-tests-k6/src/tests/flows/present-proof-flow-test.ts b/tests/performance-tests/atala-performance-tests-k6/src/tests/flows/present-proof-flow-test.ts index fe17b7148e..667c0d4c90 100644 --- a/tests/performance-tests/atala-performance-tests-k6/src/tests/flows/present-proof-flow-test.ts +++ b/tests/performance-tests/atala-performance-tests-k6/src/tests/flows/present-proof-flow-test.ts @@ -1,10 +1,24 @@ import { group } from 'k6'; import { Options } from 'k6/options'; import { Issuer, Holder, Verifier } from '../../actors'; +import { CredentialSchemaResponse } from '@input-output-hk/prism-typescript-client'; export let options: Options = { - vus: 1, - iterations: 1 + scenarios: { + smoke: { + executor: 'constant-vus', + vus: 5, + duration: "3m", + }, + }, + thresholds: { + http_req_failed: [{ + threshold: 'rate==0', + abortOnFail: true, + }], + http_req_duration: ['p(95)<=500'], + checks: ['rate==1'], + }, }; const issuer = new Issuer(); @@ -17,16 +31,21 @@ export function setup() { issuer.publishDid(); }); + group('Issuer creates credential schema', function () { + issuer.createCredentialSchema(); + }); + group('Holder creates unpublished DID', function () { holder.createUnpublishedDid(); }); - return { issuerDid: issuer.did, holderDid: holder.did }; + return { issuerDid: issuer.did, holderDid: holder.did, issuerSchema: issuer.schema }; } -export default (data: { issuerDid: string; holderDid: string; }) => { +export default (data: { issuerDid: string; holderDid: string; issuerSchema: CredentialSchemaResponse; }) => { issuer.did = data.issuerDid; + issuer.schema = data.issuerSchema; holder.did = data.holderDid; group('Holder connects with Issuer', function () { @@ -39,7 +58,7 @@ export default (data: { issuerDid: string; holderDid: string; }) => { group('Issuer creates credential offer for Holder', function () { issuer.createCredentialOffer(); issuer.waitForCredentialOfferToBeSent(); - holder.waitAndAcceptCredentialOffer(); + holder.waitAndAcceptCredentialOffer(issuer.credential!.thid); issuer.receiveCredentialRequest(); issuer.issueCredential(); issuer.waitForCredentialToBeSent(); @@ -55,7 +74,7 @@ export default (data: { issuerDid: string; holderDid: string; }) => { group('Verifier requests proof from Holder', function () { verifier.requestProof(); - holder.waitAndAcceptProofRequest(); + holder.waitAndAcceptProofRequest(verifier.presentation!.thid); verifier.acknowledgeProof(); }); diff --git a/tests/performance-tests/atala-performance-tests-k6/yarn.lock b/tests/performance-tests/atala-performance-tests-k6/yarn.lock index 711d66692a..594d94eda9 100644 --- a/tests/performance-tests/atala-performance-tests-k6/yarn.lock +++ b/tests/performance-tests/atala-performance-tests-k6/yarn.lock @@ -904,14 +904,17 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@input-output-hk/prism-typescript-client@0.1.0": - version "0.1.0" - resolved "https://npm.pkg.github.com/download/@input-output-hk/prism-typescript-client/0.1.0/9e88016b6237d734adff215da45b6e318b7c1af1#9e88016b6237d734adff215da45b6e318b7c1af1" - integrity sha512-9wF7tCUrusEXCBx2tJpSy02WdIxpXmwNNPS8vxNUY09sfBIWItkSl3YGS8XwcKAOpGBHIda5Q3PsL9hmdFtIwA== +"@input-output-hk/prism-typescript-client@1.9.2": + version "1.9.2" + resolved "https://npm.pkg.github.com/download/@input-output-hk/prism-typescript-client/1.9.2/f3afcb132244411035806306a6b52fd96f7d1ae1#f3afcb132244411035806306a6b52fd96f7d1ae1" + integrity sha512-pg/EdLmx5jIpZhNGLpqW/A6rCwv+BXRNgwHCARWPXlr0XYF3+6SYQhJVpOTkLmYV+ufCkAsVS28BlfZq6XHzFA== dependencies: + "@types/node" "*" + "@types/node-fetch" "^2.5.7" es6-promise "^4.2.4" + form-data "^2.5.0" + node-fetch "^2.6.0" url-parse "^1.4.3" - whatwg-fetch "^3.0.0" "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" @@ -1025,6 +1028,14 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== +"@types/node-fetch@^2.5.7": + version "2.6.4" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.4.tgz#1bc3a26de814f6bf466b25aeb1473fa1afe6a660" + integrity sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + "@types/node@*": version "20.3.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.2.tgz#fa6a90f2600e052a03c18b8cb3fd83dd4e599898" @@ -1362,6 +1373,11 @@ array-uniq@^1.0.1: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + babel-loader@8.2.2: version "8.2.2" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" @@ -1488,6 +1504,13 @@ colorette@^1.2.1: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== +combined-stream@^1.0.6, combined-stream@^1.0.8: + 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@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -1561,6 +1584,11 @@ del@^4.1.1: pify "^4.0.1" rimraf "^2.6.3" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -1730,6 +1758,24 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" +form-data@^2.5.0: + 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" + +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -2062,7 +2108,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.27: +mime-types@^2.1.12, mime-types@^2.1.27: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -2096,6 +2142,13 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +node-fetch@^2.6.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" + integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== + dependencies: + whatwg-url "^5.0.0" + node-releases@^2.0.12: version "2.0.12" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039" @@ -2491,6 +2544,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + typescript@4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" @@ -2542,6 +2600,11 @@ url-parse@^1.4.3: querystringify "^2.1.1" requires-port "^1.0.0" +uuid@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + v8-compile-cache@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" @@ -2555,6 +2618,11 @@ watchpack@^2.0.0, watchpack@^2.4.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + webpack-cli@4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.6.0.tgz#27ae86bfaec0cf393fcfd58abdc5a229ad32fd16" @@ -2662,10 +2730,13 @@ webpack@^5: watchpack "^2.4.0" webpack-sources "^3.2.3" -whatwg-fetch@^3.0.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" - integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" which@^2.0.1: version "2.0.2"