From 7c428db680aba26c0d7b7fca09f92d443b2ec1ee Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 30 Mar 2022 17:20:01 +0200 Subject: [PATCH 01/41] (chore): ported wrappers CLI code --- packages/cli/package.json | 5 + .../publishers/wrappers/ConnectionService.ts | 107 ++++++++++++++++ .../publishers/wrappers/PasswordService.ts | 47 +++++++ .../lib/publishers/wrappers/WrapperService.ts | 120 ++++++++++++++++++ .../cli/src/lib/publishers/wrappers/config.ts | 20 +++ .../cli/src/lib/publishers/wrappers/index.ts | 1 + .../cli/src/lib/publishers/wrappers/utils.ts | 44 +++++++ .../src/__tests__/Web3ApiClient.spec.ts | 2 +- 8 files changed, 345 insertions(+), 1 deletion(-) create mode 100644 packages/cli/src/lib/publishers/wrappers/ConnectionService.ts create mode 100644 packages/cli/src/lib/publishers/wrappers/PasswordService.ts create mode 100644 packages/cli/src/lib/publishers/wrappers/WrapperService.ts create mode 100644 packages/cli/src/lib/publishers/wrappers/config.ts create mode 100644 packages/cli/src/lib/publishers/wrappers/index.ts create mode 100644 packages/cli/src/lib/publishers/wrappers/utils.ts diff --git a/packages/cli/package.json b/packages/cli/package.json index f18ecbb447..91ff0665ee 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -40,6 +40,11 @@ "@web3api/schema-bind": "0.0.1-prealpha.69", "@web3api/schema-compose": "0.0.1-prealpha.69", "@web3api/schema-parse": "0.0.1-prealpha.69", + "ethers": "5.6.2", + "@ensdomains/ensjs": "^2.0.1", + "content-hash": "^2.5.2", + "form-data": "^4.0.0", + "prompt": "1.2.2", "assemblyscript": "0.19.1", "axios": "0.21.2", "chalk": "4.1.0", diff --git a/packages/cli/src/lib/publishers/wrappers/ConnectionService.ts b/packages/cli/src/lib/publishers/wrappers/ConnectionService.ts new file mode 100644 index 0000000000..a815828597 --- /dev/null +++ b/packages/cli/src/lib/publishers/wrappers/ConnectionService.ts @@ -0,0 +1,107 @@ +import { PasswordService } from "./Password"; + +import path from "path"; +import fs from "fs"; +import { ethers, Signer, Wallet } from "ethers"; + +export interface Connection { + provider: string; + wallet: Wallet; +} + +export interface ConnectionContainer { + [networkName: string]: EncryptedConnection; +} + +export interface EncryptedConnection { + provider: string; + encryptedKey: string; +} + +export class ConnectionService { + private get secretFilePath(): string { + return path.join(__dirname, "./.secret"); + } + + constructor(private passwordService: PasswordService) {} + + async getSigner(networkName: string): Promise { + const password = await this.passwordService.getPassword(); + + const connectionContainer = this.getConnectionContainer(); + + if (connectionContainer[networkName] === undefined) { + throw new Error(`No connection saved for network ${networkName}`); + } + + const account = await this.decryptConnection( + connectionContainer[networkName], + password + ); + + const signer = account.wallet.connect( + new ethers.providers.JsonRpcProvider(account.provider) + ); + + return signer; + } + + async saveConnectionForNetwork( + networkName: string, + provider: string, + privateKey: string + ): Promise { + const password = await this.passwordService.getPassword(); + + const connectionContainer = this.getConnectionContainer(); + + connectionContainer[networkName] = await this.encryptConnection( + provider, + privateKey, + password + ); + + this.saveConnectionContainer(connectionContainer); + } + + async decryptConnection( + encryptedConnection: EncryptedConnection, + password: string + ): Promise { + return { + provider: encryptedConnection.provider, + wallet: await ethers.Wallet.fromEncryptedJson( + encryptedConnection.encryptedKey, + password + ), + } as Connection; + } + + async encryptConnection( + provider: string, + privateKey: string, + password: string + ): Promise { + const encryptedKey = await new ethers.Wallet(privateKey).encrypt(password); + + return { + provider, + encryptedKey, + } as EncryptedConnection; + } + + private getConnectionContainer(): ConnectionContainer { + return fs.existsSync(this.secretFilePath) + ? JSON.parse(fs.readFileSync(this.secretFilePath, { encoding: "utf-8" })) + : {}; + } + + private saveConnectionContainer( + connectionContainer: ConnectionContainer + ): void { + fs.writeFileSync(this.secretFilePath, JSON.stringify(connectionContainer), { + encoding: "utf-8", + }); + console.log("Saved secret"); + } +} diff --git a/packages/cli/src/lib/publishers/wrappers/PasswordService.ts b/packages/cli/src/lib/publishers/wrappers/PasswordService.ts new file mode 100644 index 0000000000..30c4905754 --- /dev/null +++ b/packages/cli/src/lib/publishers/wrappers/PasswordService.ts @@ -0,0 +1,47 @@ +import { promptForPassword } from "./utils"; + +import fs from "fs"; +import path from "path"; + +export class PasswordService { + private password?: string; + private get passwordFilePath(): string { + return path.join(__dirname, "./.password"); + } + + async getPassword(): Promise { + if (this.password) { + return this.password; + } else if (fs.existsSync(this.passwordFilePath)) { + this.password = fs.readFileSync(this.passwordFilePath, { + encoding: "utf-8", + }); + } else { + this.password = await promptForPassword(); + } + + return this.password as string; + } + + setPassword(password: string | undefined): void { + this.password = password; + } + + savePassword(): void { + if (!this.password) { + throw Error("No password provided"); + } + + fs.writeFileSync(this.passwordFilePath, this.password, { + encoding: "utf-8", + }); + console.log("Saved password"); + } + + clearPassword(): void { + if (fs.existsSync(this.passwordFilePath)) { + fs.unlinkSync(this.passwordFilePath); + console.log("Cleared saved password"); + } + } +} diff --git a/packages/cli/src/lib/publishers/wrappers/WrapperService.ts b/packages/cli/src/lib/publishers/wrappers/WrapperService.ts new file mode 100644 index 0000000000..063bdcb35d --- /dev/null +++ b/packages/cli/src/lib/publishers/wrappers/WrapperService.ts @@ -0,0 +1,120 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +/* eslint-disable @typescript-eslint/no-var-requires */ + +import { wrappersConfig, ensConfig } from "./config"; +import { ConnectionService } from "./ConnectionService"; +import { isValidWrapDir } from "./utils"; + +import axios from "axios"; +import fs from "fs"; +import path from "path"; +import ethers from "ethers"; +import { namehash } from "ethers/lib/utils"; + +const contentHash = require("content-hash"); +const ENS = require("@ensdomains/ensjs"); +// eslint-disable-next-line @typescript-eslint/naming-convention +const FormData = require("form-data"); + +export class WrapperService { + constructor(private connectionService: ConnectionService) {} + + async addWrapper({ + onlyHash, + buildPath, + }: { + onlyHash: boolean; + buildPath: string; + }): Promise { + console.log(`Publishing build contents to IPFS...`); + + let resolvedPath = path.resolve(buildPath); + if (!isValidWrapDir(resolvedPath)) { + console.error("Could not find the build directory"); + return; + } + + if (isValidWrapDir(path.join(resolvedPath, "build"))) { + resolvedPath = path.join(resolvedPath, "build"); + } + + const data = new FormData(); + + const files = fs.readdirSync(resolvedPath); + console.log(`Found build directory at ${resolvedPath}`); + + for (const file of files) { + console.log(`Adding ${file}`); + + const filePath = path.join(resolvedPath, file); + + const buffer = fs.readFileSync(filePath); + data.append("files", buffer, { filename: file }); + } + + data.append( + "options", + JSON.stringify({ + onlyHash: onlyHash, + }) + ); + + const resp = await axios.post(wrappersConfig.gatewayURI + "/add", data, { + headers: { + ...data.getHeaders(), + }, + }); + + if (resp.status === 200 && !resp.data.error) { + const cid = resp.data.cid; + + console.log(`Publish to IPFS successful, CID: ${cid}`); + return cid; + } else if (resp.status === 200 && resp.data.error) { + console.error(resp.data.error); + } else { + console.error("Unexpected error: " + resp.status); + } + + return undefined; + } + + async publishToEns( + networkName: string, + domain: string, + cid: string + ): Promise { + console.log(`Publishing ${cid} to ${domain}...`); + + const signer = await this.connectionService.getSigner(networkName); + + const provider = signer.provider as ethers.providers.JsonRpcProvider; + const network = await provider.getNetwork(); + + const ens = new ENS.default({ + provider: signer.provider, + ensAddress: ENS.getEnsAddress(network.chainId), + }); + + const ensName = ens.name(domain); + const resolver = await ensName.getResolver(); + + const contract = new ethers.Contract( + resolver, + ensConfig.resolverAbi, + signer + ); + + const hash: string = "0x" + contentHash.fromIpfs(cid); + + console.log(`Setting contenthash for ${domain}`); + + const tx = await contract.setContenthash(namehash(domain), hash); + + console.log("Waiting for transaction: " + tx.hash); + + await tx.wait(); + + console.log(`Publish to "${networkName}" successful!`); + } +} diff --git a/packages/cli/src/lib/publishers/wrappers/config.ts b/packages/cli/src/lib/publishers/wrappers/config.ts new file mode 100644 index 0000000000..1cc15453e6 --- /dev/null +++ b/packages/cli/src/lib/publishers/wrappers/config.ts @@ -0,0 +1,20 @@ +export const wrappersConfig = { + gatewayURI: process.env.WRAPPERS_GATEWAY ?? "https://ipfs.wrappers.io", +}; + +export const ethersConfig = { + providerNetwork: + process.env.ETHEREUM_NETWORK_PROVIDER ?? "http://localhost:8545", + privateKey: process.env.ETHEREUM_PRIVATE_KEY ?? "", +}; + +export const ensConfig = { + resolverAddr: + process.env.ENS_RESOLVER_ADDR ?? + "0xf6305c19e814d2a75429Fd637d01F7ee0E77d615", + resolverAbi: [ + "function contenthash(bytes32 node) external view returns (bytes memory)", + "function setContenthash(bytes32 node, bytes calldata hash) external", + "event ContenthashChanged(bytes32 indexed node, bytes hash)", + ], +}; diff --git a/packages/cli/src/lib/publishers/wrappers/index.ts b/packages/cli/src/lib/publishers/wrappers/index.ts new file mode 100644 index 0000000000..da40c06a67 --- /dev/null +++ b/packages/cli/src/lib/publishers/wrappers/index.ts @@ -0,0 +1 @@ +export * from "./WrapperPublisher"; diff --git a/packages/cli/src/lib/publishers/wrappers/utils.ts b/packages/cli/src/lib/publishers/wrappers/utils.ts new file mode 100644 index 0000000000..1d243e5c6b --- /dev/null +++ b/packages/cli/src/lib/publishers/wrappers/utils.ts @@ -0,0 +1,44 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +/* eslint-disable @typescript-eslint/no-var-requires */ + +import fs from "fs"; +import path from "path"; + +const prompt = require("prompt"); + +export const isValidWrapDir = (buildPath: string): boolean => { + return ( + fs.existsSync(path.join(buildPath, "web3api.yaml")) || + fs.existsSync(path.join(buildPath, "web3api.yml")) || + fs.existsSync(path.join(buildPath, "web3api.json")) + ); +}; + +export const toShortString = (str: string): string => { + return str + ? `${str.slice(0, 6)}...${str.slice(-4, str.length)}` + : "undefined"; +}; + +export const promptForPassword = (): Promise => { + const schema = { + properties: { + password: { + description: "Enter your password", + hidden: true, + }, + }, + }; + + prompt.start(); + + return new Promise((resolve, reject) => { + prompt.get(schema, (error: Error, result: { password: string }) => { + if (error) { + reject(error); + } else { + resolve(result.password); + } + }); + }); +}; diff --git a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts index 5d136ede3b..81a3c52994 100644 --- a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts +++ b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts @@ -948,7 +948,7 @@ describe("Web3ApiClient", () => { ).toBe(true); }); - it("simple-storage", async () => { + it.only("simple-storage", async () => { const api = await buildAndDeployApi( `${GetPathToTestApis()}/simple-storage`, ipfsProvider, From 2d8973fe70b93f64ab1e4606f677c92b1919fb6c Mon Sep 17 00:00:00 2001 From: namesty Date: Thu, 31 Mar 2022 23:40:29 +0200 Subject: [PATCH 02/41] (feat): added deploy manifest --- packages/cli/src/lib/manifest/web3api/load.ts | 45 +++++++++ .../cli/src/lib/project/Web3ApiProject.ts | 65 ++++++++++++- .../js/core/src/manifest/formats/index.ts | 6 +- .../web3api.deploy/0.0.1-prealpha.1.ts | 35 +++++++ .../formats/web3api.deploy/deserialize.ts | 61 ++++++++++++ .../manifest/formats/web3api.deploy/index.ts | 31 ++++++ .../formats/web3api.deploy/migrate.ts | 39 ++++++++ .../formats/web3api.deploy/validate.ts | 62 ++++++++++++ .../formats/web3api/0.0.1-prealpha.8.ts | 31 ++++++ .../src/manifest/formats/web3api/index.ts | 10 +- .../src/manifest/formats/web3api/migrate.ts | 40 ++++---- ...> 0.0.1-prealpha.1_to_0.0.1-prealpha.8.ts} | 4 +- ...> 0.0.1-prealpha.2_to_0.0.1-prealpha.8.ts} | 4 +- ...> 0.0.1-prealpha.3_to_0.0.1-prealpha.8.ts} | 4 +- ...> 0.0.1-prealpha.4_to_0.0.1-prealpha.8.ts} | 4 +- ...> 0.0.1-prealpha.5_to_0.0.1-prealpha.8.ts} | 4 +- ...> 0.0.1-prealpha.6_to_0.0.1-prealpha.8.ts} | 4 +- .../0.0.1-prealpha.7_to_0.0.1-prealpha.8.ts | 13 +++ .../src/manifest/formats/web3api/validate.ts | 2 + packages/js/core/src/manifest/validators.ts | 4 + .../web3api.deploy/0.0.1-prealpha.1.json | 62 ++++++++++++ .../formats/web3api/0.0.1-prealpha.8.json | 96 +++++++++++++++++++ 22 files changed, 592 insertions(+), 34 deletions(-) create mode 100644 packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts create mode 100644 packages/js/core/src/manifest/formats/web3api.deploy/deserialize.ts create mode 100644 packages/js/core/src/manifest/formats/web3api.deploy/index.ts create mode 100644 packages/js/core/src/manifest/formats/web3api.deploy/migrate.ts create mode 100644 packages/js/core/src/manifest/formats/web3api.deploy/validate.ts create mode 100644 packages/js/core/src/manifest/formats/web3api/0.0.1-prealpha.8.ts rename packages/js/core/src/manifest/formats/web3api/migrators/{0.0.1-prealpha.1_to_0.0.1-prealpha.7.ts => 0.0.1-prealpha.1_to_0.0.1-prealpha.8.ts} (95%) rename packages/js/core/src/manifest/formats/web3api/migrators/{0.0.1-prealpha.2_to_0.0.1-prealpha.7.ts => 0.0.1-prealpha.2_to_0.0.1-prealpha.8.ts} (90%) rename packages/js/core/src/manifest/formats/web3api/migrators/{0.0.1-prealpha.3_to_0.0.1-prealpha.7.ts => 0.0.1-prealpha.3_to_0.0.1-prealpha.8.ts} (94%) rename packages/js/core/src/manifest/formats/web3api/migrators/{0.0.1-prealpha.4_to_0.0.1-prealpha.7.ts => 0.0.1-prealpha.4_to_0.0.1-prealpha.8.ts} (90%) rename packages/js/core/src/manifest/formats/web3api/migrators/{0.0.1-prealpha.5_to_0.0.1-prealpha.7.ts => 0.0.1-prealpha.5_to_0.0.1-prealpha.8.ts} (89%) rename packages/js/core/src/manifest/formats/web3api/migrators/{0.0.1-prealpha.6_to_0.0.1-prealpha.7.ts => 0.0.1-prealpha.6_to_0.0.1-prealpha.8.ts} (89%) create mode 100644 packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.7_to_0.0.1-prealpha.8.ts create mode 100644 packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json create mode 100644 packages/manifest-schemas/formats/web3api/0.0.1-prealpha.8.json diff --git a/packages/cli/src/lib/manifest/web3api/load.ts b/packages/cli/src/lib/manifest/web3api/load.ts index 19519b22c0..b8e570004f 100644 --- a/packages/cli/src/lib/manifest/web3api/load.ts +++ b/packages/cli/src/lib/manifest/web3api/load.ts @@ -4,15 +4,18 @@ import { Web3ApiManifest, BuildManifest, MetaManifest, + DeployManifest, deserializeWeb3ApiManifest, deserializeBuildManifest, deserializeMetaManifest, + deserializeDeployManifest, } from "@web3api/core-js"; import { Schema as JsonSchema } from "jsonschema"; import path from "path"; import fs from "fs"; export const defaultWeb3ApiManifest = ["web3api.yaml", "web3api.yml"]; +export const defaultBuildPath = "./build"; export async function loadWeb3ApiManifest( manifestPath: string, @@ -108,6 +111,48 @@ export async function loadBuildManifest( } } +export const defaultDeployManifest = [ + "web3api.deploy.yaml", + "web3api.deploy.yml", +]; + +export async function loadDeployManifest( + manifestPath: string, + quiet = false +): Promise { + const run = (): Promise => { + const manifest = fs.readFileSync(manifestPath, "utf-8"); + + if (!manifest) { + const noLoadMessage = intlMsg.lib_helpers_manifest_unableToLoad({ + path: `${manifestPath}`, + }); + throw Error(noLoadMessage); + } + + try { + const result = deserializeDeployManifest(manifest); + return Promise.resolve(result); + } catch (e) { + return Promise.reject(e); + } + }; + + if (quiet) { + return await run(); + } else { + manifestPath = displayPath(manifestPath); + return (await withSpinner( + intlMsg.lib_helpers_manifest_loadText({ path: manifestPath }), + intlMsg.lib_helpers_manifest_loadError({ path: manifestPath }), + intlMsg.lib_helpers_manifest_loadWarning({ path: manifestPath }), + async (_spinner) => { + return await run(); + } + )) as DeployManifest; + } +} + export const defaultMetaManifest = ["web3api.meta.yaml", "web3api.meta.yml"]; export async function loadMetaManifest( diff --git a/packages/cli/src/lib/project/Web3ApiProject.ts b/packages/cli/src/lib/project/Web3ApiProject.ts index 4664c7cdc3..c4f12e7d8e 100644 --- a/packages/cli/src/lib/project/Web3ApiProject.ts +++ b/packages/cli/src/lib/project/Web3ApiProject.ts @@ -14,7 +14,12 @@ import { intlMsg, } from ".."; -import { Web3ApiManifest, BuildManifest, MetaManifest } from "@web3api/core-js"; +import { + Web3ApiManifest, + BuildManifest, + MetaManifest, + DeployManifest, +} from "@web3api/core-js"; import { getCommonPath, normalizePath } from "@web3api/os-js"; import regexParser from "regex-parser"; import path from "path"; @@ -32,12 +37,14 @@ const cacheLayout = { export interface Web3ApiProjectConfig extends ProjectConfig { web3apiManifestPath: string; buildManifestPath?: string; + deployManifestPath?: string; metaManifestPath?: string; } export class Web3ApiProject extends Project { private _web3apiManifest: Web3ApiManifest | undefined; private _buildManifest: BuildManifest | undefined; + private _deployManifest: DeployManifest | undefined; private _metaManifest: MetaManifest | undefined; private _defaultBuildManifestCached = false; @@ -51,6 +58,7 @@ export class Web3ApiProject extends Project { this._web3apiManifest = undefined; this._buildManifest = undefined; this._metaManifest = undefined; + this._deployManifest = undefined; this._defaultBuildManifestCached = false; this.resetCache(); } @@ -311,6 +319,53 @@ export class Web3ApiProject extends Project { } } + /// Web3API Deploy Manifest (web3api.deploy.yaml) + + public async getDeployManifestPath(): Promise { + const web3apiManifest = await this.getManifest(); + + // If a custom deploy manifest path is configured + if (this._config.deployManifestPath) { + return this._config.deployManifestPath; + } + // If the web3api.yaml manifest specifies a custom deploy manifest + else if (web3apiManifest.deploy) { + this._config.deployManifestPath = path.join( + this.getManifestDir(), + web3apiManifest.deploy + ); + return this._config.deployManifestPath; + } + // No deploy manifest found + else { + return undefined; + } + } + + public async getDeployManifestDir(): Promise { + const manifestPath = await this.getDeployManifestPath(); + + if (manifestPath) { + return path.dirname(manifestPath); + } else { + return undefined; + } + } + + public async getDeployManifest(): Promise { + if (!this._deployManifest) { + const manifestPath = await this.getDeployManifestPath(); + + if (manifestPath) { + this._deployManifest = await loadDeployManifest( + manifestPath, + this.quiet + ); + } + } + return this._deployManifest; + } + /// Web3API Meta Manifest (web3api.build.yaml) public async getMetaManifestPath(): Promise { @@ -374,6 +429,14 @@ export class Web3ApiProject extends Project { ); } + const deployManifestPath = await this.getDeployManifestPath(); + + if (deployManifestPath) { + paths.push( + absolute ? deployManifestPath : path.relative(root, deployManifestPath) + ); + } + return paths; } diff --git a/packages/js/core/src/manifest/formats/index.ts b/packages/js/core/src/manifest/formats/index.ts index 2c74cef5c2..71f0d1e247 100644 --- a/packages/js/core/src/manifest/formats/index.ts +++ b/packages/js/core/src/manifest/formats/index.ts @@ -1,14 +1,16 @@ export * from "./web3api"; export * from "./web3api.build"; +export * from "./web3api.deploy"; export * from "./web3api.meta"; export * from "./web3api.plugin"; export * from "./web3api.app"; import { Web3ApiManifest } from "./web3api"; import { BuildManifest } from "./web3api.build"; +import { DeployManifest } from "./web3api.deploy"; import { MetaManifest } from "./web3api.meta"; -export type ManifestArtifactType = "web3api" | "meta" | "build"; +export type ManifestArtifactType = "web3api" | "meta" | "build" | "deploy"; export type AnyManifestArtifact< TManifestType extends ManifestArtifactType @@ -16,6 +18,8 @@ export type AnyManifestArtifact< ? Web3ApiManifest : TManifestType extends "build" ? BuildManifest + : TManifestType extends "deploy" + ? DeployManifest : TManifestType extends "meta" ? MetaManifest : never; diff --git a/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts b/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts new file mode 100644 index 0000000000..68fd97b7bf --- /dev/null +++ b/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts @@ -0,0 +1,35 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/* tslint:disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + +export interface DeployManifest { + format: "0.0.1-prealpha.1"; + deployments?: { + name: string; + deploy: { + package?: string; + config?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.*$". + */ + [k: string]: string | number; + }; + }; + publish: { + package?: string; + config?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.*$". + */ + [k: string]: string | number; + }; + }; + }[]; + __type: "DeployManifest"; +} diff --git a/packages/js/core/src/manifest/formats/web3api.deploy/deserialize.ts b/packages/js/core/src/manifest/formats/web3api.deploy/deserialize.ts new file mode 100644 index 0000000000..06b9345ed9 --- /dev/null +++ b/packages/js/core/src/manifest/formats/web3api.deploy/deserialize.ts @@ -0,0 +1,61 @@ +/* eslint-disable */ +/** + * This file was automatically generated by scripts/manifest/deserialize-ts.mustache. + * DO NOT MODIFY IT BY HAND. Instead, modify scripts/manifest/deserialize-ts.mustache, + * and run node ./scripts/manifest/generateFormatTypes.js to regenerate this file. + */ + +import { + DeployManifest, + AnyDeployManifest, + migrateDeployManifest, + validateDeployManifest, + latestDeployManifestFormat, +} from "."; +import { DeserializeManifestOptions } from "../../"; + +import { compare } from "semver"; +import YAML from "js-yaml"; +import { Tracer } from "@web3api/tracing-js"; + +export const deserializeDeployManifest = Tracer.traceFunc( + "core: deserializeDeployManifest", + (manifest: string, options?: DeserializeManifestOptions): DeployManifest => { + let anyDeployManifest: AnyDeployManifest | undefined; + try { + anyDeployManifest = JSON.parse(manifest) as AnyDeployManifest; + } catch (e) { + anyDeployManifest = YAML.safeLoad(manifest) as + | AnyDeployManifest + | undefined; + } + + if (!anyDeployManifest) { + throw Error(`Unable to parse DeployManifest: ${manifest}`); + } + + if (!options || !options.noValidate) { + validateDeployManifest(anyDeployManifest, options?.extSchema); + } + + anyDeployManifest.__type = "DeployManifest"; + + const versionCompare = compare( + anyDeployManifest.format, + latestDeployManifestFormat + ); + + if (versionCompare === -1) { + // Upgrade + return migrateDeployManifest(anyDeployManifest, latestDeployManifestFormat); + } else if (versionCompare === 1) { + // Downgrade + throw Error( + `Cannot downgrade Web3API version ${anyDeployManifest.format}, please upgrade your Web3ApiClient package.` + ); + } else { + // Latest + return anyDeployManifest as DeployManifest; + } + } +); diff --git a/packages/js/core/src/manifest/formats/web3api.deploy/index.ts b/packages/js/core/src/manifest/formats/web3api.deploy/index.ts new file mode 100644 index 0000000000..4584c34df1 --- /dev/null +++ b/packages/js/core/src/manifest/formats/web3api.deploy/index.ts @@ -0,0 +1,31 @@ +/* eslint-disable */ +/** + * This file was automatically generated by scripts/manifest/index-ts.mustache. + * DO NOT MODIFY IT BY HAND. Instead, modify scripts/manifest/index-ts.mustache, + * and run node ./scripts/manifest/generateFormatTypes.js to regenerate this file. + */ + +import { + DeployManifest as DeployManifest0_0_1_prealpha_1 +} from "./0.0.1-prealpha.1"; + +export { + DeployManifest0_0_1_prealpha_1, +}; + +export enum DeployManifestFormats { + "0.0.1-prealpha.1" = "0.0.1-prealpha.1", +} + +export type AnyDeployManifest = + | DeployManifest0_0_1_prealpha_1 + +export type DeployManifest = DeployManifest0_0_1_prealpha_1; + +export const latestDeployManifestFormat = DeployManifestFormats["0.0.1-prealpha.1"] + +export { migrateDeployManifest } from "./migrate"; + +export { deserializeDeployManifest } from "./deserialize"; + +export { validateDeployManifest } from "./validate"; diff --git a/packages/js/core/src/manifest/formats/web3api.deploy/migrate.ts b/packages/js/core/src/manifest/formats/web3api.deploy/migrate.ts new file mode 100644 index 0000000000..2fc59247af --- /dev/null +++ b/packages/js/core/src/manifest/formats/web3api.deploy/migrate.ts @@ -0,0 +1,39 @@ +/* eslint-disable */ +/** + * This file was automatically generated by scripts/manifest/migrate-ts.mustache. + * DO NOT MODIFY IT BY HAND. Instead, modify scripts/manifest/migrate-ts.mustache, + * and run node ./scripts/manifest/generateFormatTypes.js to regenerate this file. + */ +import { + AnyDeployManifest, + DeployManifest, + DeployManifestFormats, + latestDeployManifestFormat +} from "."; + + +import { Tracer } from "@web3api/tracing-js"; + +type Migrator = { + [key in DeployManifestFormats]?: (m: AnyDeployManifest) => DeployManifest; +}; + +export const migrators: Migrator = { +}; + +export const migrateDeployManifest = Tracer.traceFunc( + "core: migrateDeployManifest", + (manifest: AnyDeployManifest, to: DeployManifestFormats): DeployManifest => { + const from = manifest.format as DeployManifestFormats; + + if (from === latestDeployManifestFormat) { + return manifest as DeployManifest; + } + + if (!(from in DeployManifestFormats)) { + throw new Error(`Unrecognized DeployManifestFormat "${manifest.format}"`); + } + + throw new Error(`This should never happen, DeployManifest migrators is empty. from: ${from}, to: ${to}`); + } +); diff --git a/packages/js/core/src/manifest/formats/web3api.deploy/validate.ts b/packages/js/core/src/manifest/formats/web3api.deploy/validate.ts new file mode 100644 index 0000000000..5ef9be557d --- /dev/null +++ b/packages/js/core/src/manifest/formats/web3api.deploy/validate.ts @@ -0,0 +1,62 @@ +/* eslint-disable */ +/** + * This file was automatically generated by scripts/manifest/validate-ts.mustache. + * DO NOT MODIFY IT BY HAND. Instead, modify scripts/manifest/validate-ts.mustache, + * and run node ./scripts/manifest/generateFormatTypes.js to regenerate this file. + */ +import { + AnyDeployManifest, + DeployManifestFormats +} from "."; +import * as Validators from "../../validators"; + +import schema_0_0_1_prealpha_1 from "@web3api/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json"; +import { Tracer } from "@web3api/tracing-js" + +import { + Schema, + Validator, + ValidationError, + ValidatorResult +} from "jsonschema"; + +type DeployManifestSchemas = { + [key in DeployManifestFormats]: Schema | undefined +}; + +const schemas: DeployManifestSchemas = { + "0.0.1-prealpha.1": schema_0_0_1_prealpha_1, +}; + +const validator = new Validator(); + +Validator.prototype.customFormats.packageOrPath = Validators.packageOrPath; + +export const validateDeployManifest = Tracer.traceFunc( + "core: validateDeployManifest", + ( + manifest: AnyDeployManifest, + extSchema: Schema | undefined = undefined + ): void => { + const schema = schemas[manifest.format as DeployManifestFormats]; + + if (!schema) { + throw Error(`Unrecognized DeployManifest schema format "${manifest.format}"\nmanifest: ${JSON.stringify(manifest, null, 2)}`); + } + + const throwIfErrors = (result: ValidatorResult) => { + if (result.errors.length) { + throw new Error([ + `Validation errors encountered while sanitizing DeployManifest format ${manifest.format}`, + ...result.errors.map((error: ValidationError) => error.toString()) + ].join("\n")); + } + }; + + throwIfErrors(validator.validate(manifest, schema)); + + if (extSchema) { + throwIfErrors(validator.validate(manifest, extSchema)); + } + } +); diff --git a/packages/js/core/src/manifest/formats/web3api/0.0.1-prealpha.8.ts b/packages/js/core/src/manifest/formats/web3api/0.0.1-prealpha.8.ts new file mode 100644 index 0000000000..b91746ec0e --- /dev/null +++ b/packages/js/core/src/manifest/formats/web3api/0.0.1-prealpha.8.ts @@ -0,0 +1,31 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/* tslint:disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + +export interface Web3ApiManifest { + format: "0.0.1-prealpha.8"; + name: string; + build?: string; + meta?: string; + deploy?: string; + language: string; + modules: { + mutation?: { + schema: string; + module?: string; + }; + query?: { + schema: string; + module?: string; + }; + }; + import_redirects?: { + uri: string; + schema: string; + }[]; + __type: "Web3ApiManifest"; +} diff --git a/packages/js/core/src/manifest/formats/web3api/index.ts b/packages/js/core/src/manifest/formats/web3api/index.ts index bbfbadfe29..119e2b98f4 100644 --- a/packages/js/core/src/manifest/formats/web3api/index.ts +++ b/packages/js/core/src/manifest/formats/web3api/index.ts @@ -26,6 +26,9 @@ import { import { Web3ApiManifest as Web3ApiManifest0_0_1_prealpha_7 } from "./0.0.1-prealpha.7"; +import { + Web3ApiManifest as Web3ApiManifest0_0_1_prealpha_8 +} from "./0.0.1-prealpha.8"; export { Web3ApiManifest0_0_1_prealpha_1, @@ -35,6 +38,7 @@ export { Web3ApiManifest0_0_1_prealpha_5, Web3ApiManifest0_0_1_prealpha_6, Web3ApiManifest0_0_1_prealpha_7, + Web3ApiManifest0_0_1_prealpha_8, }; export enum Web3ApiManifestFormats { @@ -45,6 +49,7 @@ export enum Web3ApiManifestFormats { "0.0.1-prealpha.5" = "0.0.1-prealpha.5", "0.0.1-prealpha.6" = "0.0.1-prealpha.6", "0.0.1-prealpha.7" = "0.0.1-prealpha.7", + "0.0.1-prealpha.8" = "0.0.1-prealpha.8", } export type AnyWeb3ApiManifest = @@ -55,10 +60,11 @@ export type AnyWeb3ApiManifest = | Web3ApiManifest0_0_1_prealpha_5 | Web3ApiManifest0_0_1_prealpha_6 | Web3ApiManifest0_0_1_prealpha_7 + | Web3ApiManifest0_0_1_prealpha_8 -export type Web3ApiManifest = Web3ApiManifest0_0_1_prealpha_7; +export type Web3ApiManifest = Web3ApiManifest0_0_1_prealpha_8; -export const latestWeb3ApiManifestFormat = Web3ApiManifestFormats["0.0.1-prealpha.7"] +export const latestWeb3ApiManifestFormat = Web3ApiManifestFormats["0.0.1-prealpha.8"] export { migrateWeb3ApiManifest } from "./migrate"; diff --git a/packages/js/core/src/manifest/formats/web3api/migrate.ts b/packages/js/core/src/manifest/formats/web3api/migrate.ts index fcf623fd0b..8bc2ba0e4a 100644 --- a/packages/js/core/src/manifest/formats/web3api/migrate.ts +++ b/packages/js/core/src/manifest/formats/web3api/migrate.ts @@ -12,23 +12,26 @@ import { } from "."; import { - migrate as migrate_0_0_1_prealpha_1_to_0_0_1_prealpha_7 -} from "./migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.7"; + migrate as migrate_0_0_1_prealpha_1_to_0_0_1_prealpha_8 +} from "./migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.8"; import { - migrate as migrate_0_0_1_prealpha_2_to_0_0_1_prealpha_7 -} from "./migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.7"; + migrate as migrate_0_0_1_prealpha_2_to_0_0_1_prealpha_8 +} from "./migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.8"; import { - migrate as migrate_0_0_1_prealpha_3_to_0_0_1_prealpha_7 -} from "./migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.7"; + migrate as migrate_0_0_1_prealpha_3_to_0_0_1_prealpha_8 +} from "./migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.8"; import { - migrate as migrate_0_0_1_prealpha_4_to_0_0_1_prealpha_7 -} from "./migrators/0.0.1-prealpha.4_to_0.0.1-prealpha.7"; + migrate as migrate_0_0_1_prealpha_4_to_0_0_1_prealpha_8 +} from "./migrators/0.0.1-prealpha.4_to_0.0.1-prealpha.8"; import { - migrate as migrate_0_0_1_prealpha_5_to_0_0_1_prealpha_7 -} from "./migrators/0.0.1-prealpha.5_to_0.0.1-prealpha.7"; + migrate as migrate_0_0_1_prealpha_5_to_0_0_1_prealpha_8 +} from "./migrators/0.0.1-prealpha.5_to_0.0.1-prealpha.8"; import { - migrate as migrate_0_0_1_prealpha_6_to_0_0_1_prealpha_7 -} from "./migrators/0.0.1-prealpha.6_to_0.0.1-prealpha.7"; + migrate as migrate_0_0_1_prealpha_6_to_0_0_1_prealpha_8 +} from "./migrators/0.0.1-prealpha.6_to_0.0.1-prealpha.8"; +import { + migrate as migrate_0_0_1_prealpha_7_to_0_0_1_prealpha_8 +} from "./migrators/0.0.1-prealpha.7_to_0.0.1-prealpha.8"; import { Tracer } from "@web3api/tracing-js"; @@ -37,12 +40,13 @@ type Migrator = { }; export const migrators: Migrator = { - "0.0.1-prealpha.1": migrate_0_0_1_prealpha_1_to_0_0_1_prealpha_7, - "0.0.1-prealpha.2": migrate_0_0_1_prealpha_2_to_0_0_1_prealpha_7, - "0.0.1-prealpha.3": migrate_0_0_1_prealpha_3_to_0_0_1_prealpha_7, - "0.0.1-prealpha.4": migrate_0_0_1_prealpha_4_to_0_0_1_prealpha_7, - "0.0.1-prealpha.5": migrate_0_0_1_prealpha_5_to_0_0_1_prealpha_7, - "0.0.1-prealpha.6": migrate_0_0_1_prealpha_6_to_0_0_1_prealpha_7, + "0.0.1-prealpha.1": migrate_0_0_1_prealpha_1_to_0_0_1_prealpha_8, + "0.0.1-prealpha.2": migrate_0_0_1_prealpha_2_to_0_0_1_prealpha_8, + "0.0.1-prealpha.3": migrate_0_0_1_prealpha_3_to_0_0_1_prealpha_8, + "0.0.1-prealpha.4": migrate_0_0_1_prealpha_4_to_0_0_1_prealpha_8, + "0.0.1-prealpha.5": migrate_0_0_1_prealpha_5_to_0_0_1_prealpha_8, + "0.0.1-prealpha.6": migrate_0_0_1_prealpha_6_to_0_0_1_prealpha_8, + "0.0.1-prealpha.7": migrate_0_0_1_prealpha_7_to_0_0_1_prealpha_8, }; export const migrateWeb3ApiManifest = Tracer.traceFunc( diff --git a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.7.ts b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.8.ts similarity index 95% rename from packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.7.ts rename to packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.8.ts index 0258f0865b..d40c497796 100644 --- a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.7.ts +++ b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.8.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { Web3ApiManifest as OldManifest } from "../0.0.1-prealpha.1"; -import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.7"; +import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.8"; export function migrate(old: OldManifest): NewManifest { delete old.repository; @@ -15,7 +15,7 @@ export function migrate(old: OldManifest): NewManifest { return { __type: "Web3ApiManifest", - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", name: "Unnamed", language, modules: { diff --git a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.7.ts b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.8.ts similarity index 90% rename from packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.7.ts rename to packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.8.ts index c7a991c374..a4c6f944c6 100644 --- a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.7.ts +++ b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.8.ts @@ -1,14 +1,14 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { Web3ApiManifest as OldManifest } from "../0.0.1-prealpha.2"; -import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.7"; +import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.8"; export function migrate(old: OldManifest): NewManifest { delete old.repository; return { ...old, __type: "Web3ApiManifest", - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", name: "Unnamed", }; } diff --git a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.7.ts b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.8.ts similarity index 94% rename from packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.7.ts rename to packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.8.ts index 56a620ede0..32bc737caf 100644 --- a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.7.ts +++ b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.8.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { Web3ApiManifest as OldManifest } from "../0.0.1-prealpha.3"; -import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.7"; +import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.8"; export function migrate(old: OldManifest): NewManifest { delete old.repository; @@ -17,7 +17,7 @@ export function migrate(old: OldManifest): NewManifest { return { __type: "Web3ApiManifest", - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", name: "Unnamed", build: old.build, language, diff --git a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.4_to_0.0.1-prealpha.7.ts b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.4_to_0.0.1-prealpha.8.ts similarity index 90% rename from packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.4_to_0.0.1-prealpha.7.ts rename to packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.4_to_0.0.1-prealpha.8.ts index 88252e2399..403ab9fa1d 100644 --- a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.4_to_0.0.1-prealpha.7.ts +++ b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.4_to_0.0.1-prealpha.8.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { Web3ApiManifest as OldManifest } from "../0.0.1-prealpha.4"; -import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.7"; +import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.8"; export function migrate(old: OldManifest): NewManifest { delete old.repository; @@ -9,7 +9,7 @@ export function migrate(old: OldManifest): NewManifest { return { ...old, __type: "Web3ApiManifest", - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", name: "Unnamed", }; } diff --git a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.5_to_0.0.1-prealpha.7.ts b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.5_to_0.0.1-prealpha.8.ts similarity index 89% rename from packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.5_to_0.0.1-prealpha.7.ts rename to packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.5_to_0.0.1-prealpha.8.ts index 27ab376deb..9e4a77bb01 100644 --- a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.5_to_0.0.1-prealpha.7.ts +++ b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.5_to_0.0.1-prealpha.8.ts @@ -1,13 +1,13 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { Web3ApiManifest as OldManifest } from "../0.0.1-prealpha.5"; -import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.7"; +import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.8"; export function migrate(old: OldManifest): NewManifest { return { ...old, __type: "Web3ApiManifest", - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", name: "Unnamed", }; } diff --git a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.6_to_0.0.1-prealpha.7.ts b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.6_to_0.0.1-prealpha.8.ts similarity index 89% rename from packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.6_to_0.0.1-prealpha.7.ts rename to packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.6_to_0.0.1-prealpha.8.ts index 41472855ff..a373a8d292 100644 --- a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.6_to_0.0.1-prealpha.7.ts +++ b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.6_to_0.0.1-prealpha.8.ts @@ -1,13 +1,13 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { Web3ApiManifest as OldManifest } from "../0.0.1-prealpha.6"; -import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.7"; +import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.8"; export function migrate(old: OldManifest): NewManifest { return { ...old, __type: "Web3ApiManifest", - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", name: "Unnamed", }; } diff --git a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.7_to_0.0.1-prealpha.8.ts b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.7_to_0.0.1-prealpha.8.ts new file mode 100644 index 0000000000..74b76f9ecc --- /dev/null +++ b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.7_to_0.0.1-prealpha.8.ts @@ -0,0 +1,13 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + +import { Web3ApiManifest as OldManifest } from "../0.0.1-prealpha.7"; +import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.8"; + +export function migrate(old: OldManifest): NewManifest { + return { + ...old, + __type: "Web3ApiManifest", + format: "0.0.1-prealpha.8", + name: "Unnamed", + }; +} diff --git a/packages/js/core/src/manifest/formats/web3api/validate.ts b/packages/js/core/src/manifest/formats/web3api/validate.ts index 81c1021315..6d4f357fe5 100644 --- a/packages/js/core/src/manifest/formats/web3api/validate.ts +++ b/packages/js/core/src/manifest/formats/web3api/validate.ts @@ -17,6 +17,7 @@ import schema_0_0_1_prealpha_4 from "@web3api/manifest-schemas/formats/web3api/0 import schema_0_0_1_prealpha_5 from "@web3api/manifest-schemas/formats/web3api/0.0.1-prealpha.5.json"; import schema_0_0_1_prealpha_6 from "@web3api/manifest-schemas/formats/web3api/0.0.1-prealpha.6.json"; import schema_0_0_1_prealpha_7 from "@web3api/manifest-schemas/formats/web3api/0.0.1-prealpha.7.json"; +import schema_0_0_1_prealpha_8 from "@web3api/manifest-schemas/formats/web3api/0.0.1-prealpha.8.json"; import { Tracer } from "@web3api/tracing-js" import { @@ -38,6 +39,7 @@ const schemas: Web3ApiManifestSchemas = { "0.0.1-prealpha.5": schema_0_0_1_prealpha_5, "0.0.1-prealpha.6": schema_0_0_1_prealpha_6, "0.0.1-prealpha.7": schema_0_0_1_prealpha_7, + "0.0.1-prealpha.8": schema_0_0_1_prealpha_8, }; const validator = new Validator(); diff --git a/packages/js/core/src/manifest/validators.ts b/packages/js/core/src/manifest/validators.ts index a2cf1202ad..671a9d46a2 100644 --- a/packages/js/core/src/manifest/validators.ts +++ b/packages/js/core/src/manifest/validators.ts @@ -20,6 +20,10 @@ export function packageName(name: unknown): boolean { return typeof name === "string"; } +export function packageOrPath(name: unknown): boolean { + return typeof name === "string"; +} + export function packageTag(tag: unknown): boolean { return typeof tag === "string"; } diff --git a/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json b/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json new file mode 100644 index 0000000000..bc8379066d --- /dev/null +++ b/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json @@ -0,0 +1,62 @@ +{ + "id": "DeployManifest", + "type": "object", + "additionalProperties": false, + "required": [ + "format" + ], + "properties": { + "format": { + "type": "string", + "const": "0.0.1-prealpha.1" + }, + "deployments": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "deploy": { + "type": "object", + "additionalProperties": false, + "properties": { + "package": { + "type": "string", + "format": "packageOrPath" + }, + "config": { + "patternProperties": { + "^.*$": { + "type": ["string", "number"] + } + }, + "additionalProperties": false + } + } + }, + "publish": { + "type": "object", + "additionalProperties": false, + "properties": { + "package": { + "type": "string" + }, + "config": { + "patternProperties": { + "^.*$": { + "type": ["string", "number"] + } + }, + "additionalProperties": false + } + } + } + }, + "required": ["name", "deploy", "publish"] + } + } + } +} diff --git a/packages/manifest-schemas/formats/web3api/0.0.1-prealpha.8.json b/packages/manifest-schemas/formats/web3api/0.0.1-prealpha.8.json new file mode 100644 index 0000000000..32d671cba5 --- /dev/null +++ b/packages/manifest-schemas/formats/web3api/0.0.1-prealpha.8.json @@ -0,0 +1,96 @@ +{ + "id": "Web3ApiManifest", + "type": "object", + "additionalProperties": false, + "required": [ + "format", + "name", + "modules", + "language" + ], + "properties": { + "format": { + "type": "string", + "const": "0.0.1-prealpha.8" + }, + "name": { + "type": "string", + "format": "packageName" + }, + "build": { + "type": "string", + "format": "manifestFile" + }, + "meta": { + "type": "string", + "format": "manifestFile" + }, + "deploy": { + "type": "string", + "format": "manifestFile" + }, + "language": { + "type": "string", + "format": "wasmLanguage" + }, + "modules": { + "type": "object", + "additionalProperties": false, + "properties": { + "mutation": { + "type": "object", + "additionalProperties": false, + "properties": { + "schema": { + "type": "string", + "format": "graphqlFile" + }, + "module": { + "type": "string", + "format": "file" + } + }, + "required": [ + "schema" + ] + }, + "query": { + "type": "object", + "additionalProperties": false, + "properties": { + "schema": { + "type": "string", + "format": "graphqlFile" + }, + "module": { + "type": "string", + "format": "file" + } + }, + "required": [ + "schema" + ] + } + } + }, + "import_redirects": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "uri": { + "type": "string" + }, + "schema": { + "type": "string" + } + }, + "required": [ + "uri", + "schema" + ] + } + } + } +} From 64da88c87d13b818dcf9f96b6649146ddbc5a24e Mon Sep 17 00:00:00 2001 From: namesty Date: Mon, 4 Apr 2022 14:02:45 +0200 Subject: [PATCH 03/41] (chore): removed wrappers cli files --- .../publishers/wrappers/ConnectionService.ts | 107 ---------------- .../publishers/wrappers/PasswordService.ts | 47 ------- .../lib/publishers/wrappers/WrapperService.ts | 120 ------------------ .../cli/src/lib/publishers/wrappers/config.ts | 20 --- .../cli/src/lib/publishers/wrappers/index.ts | 1 - .../cli/src/lib/publishers/wrappers/utils.ts | 44 ------- 6 files changed, 339 deletions(-) delete mode 100644 packages/cli/src/lib/publishers/wrappers/ConnectionService.ts delete mode 100644 packages/cli/src/lib/publishers/wrappers/PasswordService.ts delete mode 100644 packages/cli/src/lib/publishers/wrappers/WrapperService.ts delete mode 100644 packages/cli/src/lib/publishers/wrappers/config.ts delete mode 100644 packages/cli/src/lib/publishers/wrappers/index.ts delete mode 100644 packages/cli/src/lib/publishers/wrappers/utils.ts diff --git a/packages/cli/src/lib/publishers/wrappers/ConnectionService.ts b/packages/cli/src/lib/publishers/wrappers/ConnectionService.ts deleted file mode 100644 index a815828597..0000000000 --- a/packages/cli/src/lib/publishers/wrappers/ConnectionService.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { PasswordService } from "./Password"; - -import path from "path"; -import fs from "fs"; -import { ethers, Signer, Wallet } from "ethers"; - -export interface Connection { - provider: string; - wallet: Wallet; -} - -export interface ConnectionContainer { - [networkName: string]: EncryptedConnection; -} - -export interface EncryptedConnection { - provider: string; - encryptedKey: string; -} - -export class ConnectionService { - private get secretFilePath(): string { - return path.join(__dirname, "./.secret"); - } - - constructor(private passwordService: PasswordService) {} - - async getSigner(networkName: string): Promise { - const password = await this.passwordService.getPassword(); - - const connectionContainer = this.getConnectionContainer(); - - if (connectionContainer[networkName] === undefined) { - throw new Error(`No connection saved for network ${networkName}`); - } - - const account = await this.decryptConnection( - connectionContainer[networkName], - password - ); - - const signer = account.wallet.connect( - new ethers.providers.JsonRpcProvider(account.provider) - ); - - return signer; - } - - async saveConnectionForNetwork( - networkName: string, - provider: string, - privateKey: string - ): Promise { - const password = await this.passwordService.getPassword(); - - const connectionContainer = this.getConnectionContainer(); - - connectionContainer[networkName] = await this.encryptConnection( - provider, - privateKey, - password - ); - - this.saveConnectionContainer(connectionContainer); - } - - async decryptConnection( - encryptedConnection: EncryptedConnection, - password: string - ): Promise { - return { - provider: encryptedConnection.provider, - wallet: await ethers.Wallet.fromEncryptedJson( - encryptedConnection.encryptedKey, - password - ), - } as Connection; - } - - async encryptConnection( - provider: string, - privateKey: string, - password: string - ): Promise { - const encryptedKey = await new ethers.Wallet(privateKey).encrypt(password); - - return { - provider, - encryptedKey, - } as EncryptedConnection; - } - - private getConnectionContainer(): ConnectionContainer { - return fs.existsSync(this.secretFilePath) - ? JSON.parse(fs.readFileSync(this.secretFilePath, { encoding: "utf-8" })) - : {}; - } - - private saveConnectionContainer( - connectionContainer: ConnectionContainer - ): void { - fs.writeFileSync(this.secretFilePath, JSON.stringify(connectionContainer), { - encoding: "utf-8", - }); - console.log("Saved secret"); - } -} diff --git a/packages/cli/src/lib/publishers/wrappers/PasswordService.ts b/packages/cli/src/lib/publishers/wrappers/PasswordService.ts deleted file mode 100644 index 30c4905754..0000000000 --- a/packages/cli/src/lib/publishers/wrappers/PasswordService.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { promptForPassword } from "./utils"; - -import fs from "fs"; -import path from "path"; - -export class PasswordService { - private password?: string; - private get passwordFilePath(): string { - return path.join(__dirname, "./.password"); - } - - async getPassword(): Promise { - if (this.password) { - return this.password; - } else if (fs.existsSync(this.passwordFilePath)) { - this.password = fs.readFileSync(this.passwordFilePath, { - encoding: "utf-8", - }); - } else { - this.password = await promptForPassword(); - } - - return this.password as string; - } - - setPassword(password: string | undefined): void { - this.password = password; - } - - savePassword(): void { - if (!this.password) { - throw Error("No password provided"); - } - - fs.writeFileSync(this.passwordFilePath, this.password, { - encoding: "utf-8", - }); - console.log("Saved password"); - } - - clearPassword(): void { - if (fs.existsSync(this.passwordFilePath)) { - fs.unlinkSync(this.passwordFilePath); - console.log("Cleared saved password"); - } - } -} diff --git a/packages/cli/src/lib/publishers/wrappers/WrapperService.ts b/packages/cli/src/lib/publishers/wrappers/WrapperService.ts deleted file mode 100644 index 063bdcb35d..0000000000 --- a/packages/cli/src/lib/publishers/wrappers/WrapperService.ts +++ /dev/null @@ -1,120 +0,0 @@ -/* eslint-disable @typescript-eslint/no-require-imports */ -/* eslint-disable @typescript-eslint/no-var-requires */ - -import { wrappersConfig, ensConfig } from "./config"; -import { ConnectionService } from "./ConnectionService"; -import { isValidWrapDir } from "./utils"; - -import axios from "axios"; -import fs from "fs"; -import path from "path"; -import ethers from "ethers"; -import { namehash } from "ethers/lib/utils"; - -const contentHash = require("content-hash"); -const ENS = require("@ensdomains/ensjs"); -// eslint-disable-next-line @typescript-eslint/naming-convention -const FormData = require("form-data"); - -export class WrapperService { - constructor(private connectionService: ConnectionService) {} - - async addWrapper({ - onlyHash, - buildPath, - }: { - onlyHash: boolean; - buildPath: string; - }): Promise { - console.log(`Publishing build contents to IPFS...`); - - let resolvedPath = path.resolve(buildPath); - if (!isValidWrapDir(resolvedPath)) { - console.error("Could not find the build directory"); - return; - } - - if (isValidWrapDir(path.join(resolvedPath, "build"))) { - resolvedPath = path.join(resolvedPath, "build"); - } - - const data = new FormData(); - - const files = fs.readdirSync(resolvedPath); - console.log(`Found build directory at ${resolvedPath}`); - - for (const file of files) { - console.log(`Adding ${file}`); - - const filePath = path.join(resolvedPath, file); - - const buffer = fs.readFileSync(filePath); - data.append("files", buffer, { filename: file }); - } - - data.append( - "options", - JSON.stringify({ - onlyHash: onlyHash, - }) - ); - - const resp = await axios.post(wrappersConfig.gatewayURI + "/add", data, { - headers: { - ...data.getHeaders(), - }, - }); - - if (resp.status === 200 && !resp.data.error) { - const cid = resp.data.cid; - - console.log(`Publish to IPFS successful, CID: ${cid}`); - return cid; - } else if (resp.status === 200 && resp.data.error) { - console.error(resp.data.error); - } else { - console.error("Unexpected error: " + resp.status); - } - - return undefined; - } - - async publishToEns( - networkName: string, - domain: string, - cid: string - ): Promise { - console.log(`Publishing ${cid} to ${domain}...`); - - const signer = await this.connectionService.getSigner(networkName); - - const provider = signer.provider as ethers.providers.JsonRpcProvider; - const network = await provider.getNetwork(); - - const ens = new ENS.default({ - provider: signer.provider, - ensAddress: ENS.getEnsAddress(network.chainId), - }); - - const ensName = ens.name(domain); - const resolver = await ensName.getResolver(); - - const contract = new ethers.Contract( - resolver, - ensConfig.resolverAbi, - signer - ); - - const hash: string = "0x" + contentHash.fromIpfs(cid); - - console.log(`Setting contenthash for ${domain}`); - - const tx = await contract.setContenthash(namehash(domain), hash); - - console.log("Waiting for transaction: " + tx.hash); - - await tx.wait(); - - console.log(`Publish to "${networkName}" successful!`); - } -} diff --git a/packages/cli/src/lib/publishers/wrappers/config.ts b/packages/cli/src/lib/publishers/wrappers/config.ts deleted file mode 100644 index 1cc15453e6..0000000000 --- a/packages/cli/src/lib/publishers/wrappers/config.ts +++ /dev/null @@ -1,20 +0,0 @@ -export const wrappersConfig = { - gatewayURI: process.env.WRAPPERS_GATEWAY ?? "https://ipfs.wrappers.io", -}; - -export const ethersConfig = { - providerNetwork: - process.env.ETHEREUM_NETWORK_PROVIDER ?? "http://localhost:8545", - privateKey: process.env.ETHEREUM_PRIVATE_KEY ?? "", -}; - -export const ensConfig = { - resolverAddr: - process.env.ENS_RESOLVER_ADDR ?? - "0xf6305c19e814d2a75429Fd637d01F7ee0E77d615", - resolverAbi: [ - "function contenthash(bytes32 node) external view returns (bytes memory)", - "function setContenthash(bytes32 node, bytes calldata hash) external", - "event ContenthashChanged(bytes32 indexed node, bytes hash)", - ], -}; diff --git a/packages/cli/src/lib/publishers/wrappers/index.ts b/packages/cli/src/lib/publishers/wrappers/index.ts deleted file mode 100644 index da40c06a67..0000000000 --- a/packages/cli/src/lib/publishers/wrappers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./WrapperPublisher"; diff --git a/packages/cli/src/lib/publishers/wrappers/utils.ts b/packages/cli/src/lib/publishers/wrappers/utils.ts deleted file mode 100644 index 1d243e5c6b..0000000000 --- a/packages/cli/src/lib/publishers/wrappers/utils.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable @typescript-eslint/no-require-imports */ -/* eslint-disable @typescript-eslint/no-var-requires */ - -import fs from "fs"; -import path from "path"; - -const prompt = require("prompt"); - -export const isValidWrapDir = (buildPath: string): boolean => { - return ( - fs.existsSync(path.join(buildPath, "web3api.yaml")) || - fs.existsSync(path.join(buildPath, "web3api.yml")) || - fs.existsSync(path.join(buildPath, "web3api.json")) - ); -}; - -export const toShortString = (str: string): string => { - return str - ? `${str.slice(0, 6)}...${str.slice(-4, str.length)}` - : "undefined"; -}; - -export const promptForPassword = (): Promise => { - const schema = { - properties: { - password: { - description: "Enter your password", - hidden: true, - }, - }, - }; - - prompt.start(); - - return new Promise((resolve, reject) => { - prompt.get(schema, (error: Error, result: { password: string }) => { - if (error) { - reject(error); - } else { - resolve(result.password); - } - }); - }); -}; From 7ebc5591b0d5d357edeab4c624a4671b292ccc03 Mon Sep 17 00:00:00 2001 From: namesty Date: Mon, 4 Apr 2022 14:03:45 +0200 Subject: [PATCH 04/41] (fix): corrected deploy manifest format --- .../web3api.deploy/0.0.1-prealpha.1.ts | 16 +++++--- .../formats/web3api.deploy/validate.ts | 2 +- packages/js/core/src/manifest/validators.ts | 4 -- .../web3api.deploy/0.0.1-prealpha.1.json | 38 +++++++++++++++---- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts b/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts index 68fd97b7bf..84b3246d75 100644 --- a/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts +++ b/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts @@ -8,10 +8,13 @@ export interface DeployManifest { format: "0.0.1-prealpha.1"; - deployments?: { + deployments: { name: string; - deploy: { - package?: string; + deploy?: { + package: { + name: string; + versionOrPath: string; + }; config?: { /** * This interface was referenced by `undefined`'s JSON-Schema definition @@ -20,8 +23,11 @@ export interface DeployManifest { [k: string]: string | number; }; }; - publish: { - package?: string; + publish?: { + package: { + name: string; + versionOrPath: string; + }; config?: { /** * This interface was referenced by `undefined`'s JSON-Schema definition diff --git a/packages/js/core/src/manifest/formats/web3api.deploy/validate.ts b/packages/js/core/src/manifest/formats/web3api.deploy/validate.ts index 5ef9be557d..f8b1b3bcc3 100644 --- a/packages/js/core/src/manifest/formats/web3api.deploy/validate.ts +++ b/packages/js/core/src/manifest/formats/web3api.deploy/validate.ts @@ -30,7 +30,7 @@ const schemas: DeployManifestSchemas = { const validator = new Validator(); -Validator.prototype.customFormats.packageOrPath = Validators.packageOrPath; +Validator.prototype.customFormats.packageName = Validators.packageName; export const validateDeployManifest = Tracer.traceFunc( "core: validateDeployManifest", diff --git a/packages/js/core/src/manifest/validators.ts b/packages/js/core/src/manifest/validators.ts index 671a9d46a2..a2cf1202ad 100644 --- a/packages/js/core/src/manifest/validators.ts +++ b/packages/js/core/src/manifest/validators.ts @@ -20,10 +20,6 @@ export function packageName(name: unknown): boolean { return typeof name === "string"; } -export function packageOrPath(name: unknown): boolean { - return typeof name === "string"; -} - export function packageTag(tag: unknown): boolean { return typeof tag === "string"; } diff --git a/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json b/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json index bc8379066d..1eaa16f45b 100644 --- a/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json +++ b/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json @@ -3,7 +3,8 @@ "type": "object", "additionalProperties": false, "required": [ - "format" + "format", + "deployments" ], "properties": { "format": { @@ -24,8 +25,18 @@ "additionalProperties": false, "properties": { "package": { - "type": "string", - "format": "packageOrPath" + "type": "object", + "properties": { + "name": { + "type" : "string", + "format": "packageName" + }, + "versionOrPath": { + "type": "string" + } + }, + "required": ["versionOrPath", "name"], + "additionalProperties": false }, "config": { "patternProperties": { @@ -35,14 +46,26 @@ }, "additionalProperties": false } - } + }, + "required": ["package"] }, "publish": { "type": "object", "additionalProperties": false, "properties": { "package": { - "type": "string" + "type": "object", + "properties": { + "name": { + "type" : "string", + "format": "packageName" + }, + "versionOrPath": { + "type": "string" + } + }, + "required": ["versionOrPath", "name"], + "additionalProperties": false }, "config": { "patternProperties": { @@ -52,10 +75,11 @@ }, "additionalProperties": false } - } + }, + "required": ["package"] } }, - "required": ["name", "deploy", "publish"] + "required": ["name"] } } } From 771dd1449ed4c0969b0d7004247a6d4c2aeeda92 Mon Sep 17 00:00:00 2001 From: namesty Date: Mon, 4 Apr 2022 14:04:37 +0200 Subject: [PATCH 05/41] (feat): added DeploymentManager --- .../cli/src/lib/deploy/DeploymentManager.ts | 131 ++++++++++++++++++ packages/cli/src/lib/deploy/file.ts | 45 ++++++ 2 files changed, 176 insertions(+) create mode 100644 packages/cli/src/lib/deploy/DeploymentManager.ts create mode 100644 packages/cli/src/lib/deploy/file.ts diff --git a/packages/cli/src/lib/deploy/DeploymentManager.ts b/packages/cli/src/lib/deploy/DeploymentManager.ts new file mode 100644 index 0000000000..a18315fa23 --- /dev/null +++ b/packages/cli/src/lib/deploy/DeploymentManager.ts @@ -0,0 +1,131 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +import { Web3ApiProject } from "../project"; +import { runCommand } from "../system"; +import { DirectoryEntry } from "./file"; + +import path from "path"; +import fs from "fs"; +import { DeployManifest } from "@web3api/core-js"; + +type Config = { + [k: string]: string | number; +}; + +export interface Deployer { + deploy(buildDirEntry: DirectoryEntry, config?: Config): Promise; +} + +export interface Publisher { + publish(cid: string, config?: Config): Promise; +} + +export interface Deployment { + name: string; + deployer?: Deployer; + publisher?: Publisher; + deployerConfig?: Config; + publisherConfig?: Config; +} + +export class DeploymentManager { + public static readonly cacheDirName = "deployments"; + private packagesInstalled = false; + + constructor( + private project: Web3ApiProject, + private deployManifest: DeployManifest + ) {} + + public installPackages = async (deploymentName: string): Promise => { + const deploymentManifestItem = this.findDeploymentInManifest( + deploymentName + ); + + const packages: { name: string; versionOrPath: string }[] = []; + + if (deploymentManifestItem.deploy) { + packages.push(deploymentManifestItem.deploy.package); + } + + if (deploymentManifestItem.publish) { + packages.push(deploymentManifestItem.publish.package); + } + + const packageJSON = { + name: "web3api-deploy", + version: "1.0.0", + private: true, + dependencies: packages.reduce((acc, current) => { + acc[current.name] = current.versionOrPath; + return acc; + }, {} as Record), + }; + + fs.writeFileSync( + path.join( + this.project.getCachePath(DeploymentManager.cacheDirName), + "package.json" + ), + JSON.stringify(packageJSON) + ); + + await runCommand( + `cd ${this.project.getCachePath(DeploymentManager.cacheDirName)} && npm i` + ); + + this.packagesInstalled = true; + }; + + public getDeployment = (deploymentName: string): Deployment => { + const deployment: Deployment = { + name: deploymentName, + }; + + if (!this.packagesInstalled) { + throw new Error("Packages have not been installed"); + } + + const deploymentManifestItem = this.findDeploymentInManifest( + deploymentName + ); + + const nodeModulesPath = path.join( + this.project.getCachePath(DeploymentManager.cacheDirName), + "node_modules" + ); + + if (deploymentManifestItem.deploy) { + deployment.deployer = require(path.join( + nodeModulesPath, + deploymentManifestItem.deploy.package.name + )); + + deployment.deployerConfig = deploymentManifestItem.deploy.config; + } + + if (deploymentManifestItem.publish) { + deployment.publisher = require(path.join( + nodeModulesPath, + deploymentManifestItem.publish.package.name + )); + + deployment.publisherConfig = deploymentManifestItem.publish.config; + } + + return deployment; + }; + + private findDeploymentInManifest = (deploymentName: string) => { + const deploymentManifestItem = this.deployManifest.deployments.find( + (d) => d.name === deploymentName + ); + + if (!deploymentManifestItem) { + throw new Error( + `Deployment with name '${deploymentName}' not found in manifest` + ); + } + + return deploymentManifestItem; + }; +} diff --git a/packages/cli/src/lib/deploy/file.ts b/packages/cli/src/lib/deploy/file.ts new file mode 100644 index 0000000000..941db2dd16 --- /dev/null +++ b/packages/cli/src/lib/deploy/file.ts @@ -0,0 +1,45 @@ +import fs from "fs"; +import path from "path"; + +export interface FileEntry { + name: string; + data: string; +} + +export interface DirectoryEntry { + name: string; + directories: DirectoryEntry[]; + files: FileEntry[]; +} + +export const convertFileToEntry = (pathToFile: string): FileEntry => { + const name = path.basename(pathToFile); + const data = fs.readFileSync(pathToFile, { encoding: "utf-8" }); + + return { + name, + data, + }; +}; + +export const convertDirectoryToEntry = (pathToDir: string): DirectoryEntry => { + const name = path.basename(pathToDir); + + const filesAndDirs = fs.readdirSync(pathToDir, { withFileTypes: true }); + + const files = filesAndDirs + .filter((dirent) => !dirent.isDirectory()) + .map((dirent) => convertFileToEntry(path.join(pathToDir, dirent.name))); + + const directories = filesAndDirs + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => + convertDirectoryToEntry(path.join(pathToDir, dirent.name)) + ); + + return { + name, + files, + directories, + }; +}; From d24571ae91fcd288eb868dfc14ebab2a36ed5fb0 Mon Sep 17 00:00:00 2001 From: namesty Date: Mon, 4 Apr 2022 14:05:13 +0200 Subject: [PATCH 06/41] (chore): added message translations and deploy command --- packages/cli/lang/en.json | 13 ++ packages/cli/lang/es.json | 13 ++ packages/cli/src/commands/deploy.ts | 204 ++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 packages/cli/src/commands/deploy.ts diff --git a/packages/cli/lang/en.json b/packages/cli/lang/en.json index f681307993..390d6a9d0b 100644 --- a/packages/cli/lang/en.json +++ b/packages/cli/lang/en.json @@ -25,6 +25,19 @@ "commands_build_options_w": "Automatically rebuild when changes are made (default: false)", "commands_build_options_v": "Verbose output (default: false)", "commands_build_uriViewers": "URI Viewers", + "commands_deploy_options_options": "options", + "commands_deploy_options_o_path": "path", + "commands_deploy_options_o_string": "string", + "commands_deploy_options_h": "Show usage information", + "commands_deploy_options_m": "Path to the Web3API Deploy manifest file (default: {default})", + "commands_deploy_options_n": "Name of the deployment to execute", + "commands_deploy_options_c": "Argument for deployment's publish step, in case deploy step is absent", + "commands_deploy_options_v": "Verbose output (default: false)", + "commands_deploy_options_p": "Path to the build directory", + "commands_deploy_error_manifestPathMissing": "{option} option missing {argument} argument", + "commands_deploy_error_pathMissing": "{option} option missing {argument} argument", + "commands_deploy_error_nameMissing": "{option} option missing {argument} argument", + "commands_deploy_error_cidMissing": "{option} option missing {argument} argument", "commands_codegen_description": "Auto-generate API Types", "commands_codegen_error_domain": "domain", "commands_codegen_error_optionMissingArgument": "{option} option missing {argument} argument", diff --git a/packages/cli/lang/es.json b/packages/cli/lang/es.json index 05d3ed637b..686f89cb4c 100644 --- a/packages/cli/lang/es.json +++ b/packages/cli/lang/es.json @@ -25,6 +25,19 @@ "commands_build_options_w": "Automatically rebuild when changes are made (default: false)", "commands_build_options_v": "Verbose output (default: false)", "commands_build_uriViewers": "URI Viewers", + "commands_deploy_options_options": "options", + "commands_deploy_options_o_path": "path", + "commands_deploy_options_o_string": "string", + "commands_deploy_options_h": "Show usage information", + "commands_deploy_options_m": "Path to the Web3API Deploy manifest file (default: {default})", + "commands_deploy_options_n": "Name of the deployment to execute", + "commands_deploy_options_c": "Argument for deployment's publish step, in case deploy step is absent", + "commands_deploy_options_v": "Verbose output (default: false)", + "commands_deploy_options_p": "Path to the build directory", + "commands_deploy_error_manifestPathMissing": "{option} option missing {argument} argument", + "commands_deploy_error_pathMissing": "{option} option missing {argument} argument", + "commands_deploy_error_nameMissing": "{option} option missing {argument} argument", + "commands_deploy_error_cidMissing": "{option} option missing {argument} argument", "commands_codegen_description": "Auto-generate API Types", "commands_codegen_error_domain": "domain", "commands_codegen_error_optionMissingArgument": "{option} option missing {argument} argument", diff --git a/packages/cli/src/commands/deploy.ts b/packages/cli/src/commands/deploy.ts new file mode 100644 index 0000000000..022dde416e --- /dev/null +++ b/packages/cli/src/commands/deploy.ts @@ -0,0 +1,204 @@ +/* eslint-disable prefer-const */ +import { + intlMsg, + defaultBuildPath, + Web3ApiProject, + defaultWeb3ApiManifest, + resolvePathIfExists, +} from "../lib"; +import { DeploymentManager } from "../lib/deploy/DeploymentManager"; +import { convertDirectoryToEntry } from "../lib/deploy/file"; + +import chalk from "chalk"; +import { GluegunToolbox, GluegunPrint } from "gluegun"; + +const defaultManifestStr = defaultWeb3ApiManifest.join(" | "); +const defaultOutputDirectory = defaultBuildPath; +const optionsStr = intlMsg.commands_deploy_options_options(); +const pathStr = intlMsg.commands_deploy_options_o_path(); +const strStr = intlMsg.commands_deploy_options_o_string(); + +const HELP = ` +${chalk.bold("w3 deploy")} [${optionsStr}] + +${optionsStr[0].toUpperCase() + optionsStr.slice(1)}: + -h, --help ${intlMsg.commands_deploy_options_h()} + -m, --manifest-file <${pathStr}> ${intlMsg.commands_deploy_options_m({ + default: defaultManifestStr, +})} + -n, --name <${strStr}> ${intlMsg.commands_deploy_options_n()} + -c, --cid <${strStr}> ${intlMsg.commands_deploy_options_c()} + -v, --verbose ${intlMsg.commands_deploy_options_v()} + -p, --path [<${pathStr}>]" ${intlMsg.commands_deploy_options_p()} +`; + +export default { + alias: ["b"], + description: intlMsg.commands_build_description(), + run: async (toolbox: GluegunToolbox): Promise => { + const { filesystem, parameters, print } = toolbox; + + // Options + const { h, p, m, v, n, c } = parameters.options; + let { help, path, manifestFile, verbose, name, cid } = parameters.options; + + help = help || h; + path = path || p; + verbose = verbose || v; + manifestFile = manifestFile || m; + name = name || n; + cid = cid || c; + + // Validate Params + const paramsValid = validateDeployParams(print, { + name, + cid, + path, + manifestFile, + }); + + if (help || !paramsValid) { + print.info(HELP); + if (!paramsValid) { + process.exitCode = 1; + } + return; + } + + // Resolve manifest & output directory + const manifestPaths = manifestFile + ? [manifestFile as string] + : defaultWeb3ApiManifest; + manifestFile = resolvePathIfExists(filesystem, manifestPaths); + + if (!manifestFile) { + print.error( + intlMsg.commands_build_error_manifestNotFound({ + paths: manifestPaths.join(", "), + }) + ); + return; + } + + const buildPath: string = path ?? defaultOutputDirectory; + + const project = new Web3ApiProject({ + rootCacheDir: path.dirname(manifestFile), + web3apiManifestPath: manifestFile, + quiet: verbose ? false : true, + }); + + await project.validate(); + + const deployManifest = await project.getDeployManifest(); + + if (!deployManifest) { + throw new Error("No deploy manifest"); + } + + const deploymentManager = new DeploymentManager(project, deployManifest); + + await deploymentManager.installPackages(name); + + const deployment = deploymentManager.getDeployment(name); + + if (!deployment.deployer && !cid) { + throw new Error( + `No deploy stage is present in deployment '${name}', a cid arg is required for publish` + ); + } + + const uris: string[][] = []; + let deployResult: string | undefined; + let publishResult: string | undefined; + + if (deployment.deployer) { + const buildDirEntry = convertDirectoryToEntry(buildPath); + + try { + deployResult = await deployment.deployer.deploy( + buildDirEntry, + deployment.deployerConfig + ); + + uris.push(["Deploy", deployResult]); + } catch (e) { + throw new Error( + `Deployment '${name}' deploy stage failed. Error: ${e}` + ); + } + } + + if (deployment.publisher) { + try { + publishResult = await deployment.publisher.publish( + deployResult ?? cid, + deployment.deployerConfig + ); + + uris.push(["Publish", publishResult]); + } catch (e) { + throw new Error( + `Deployment '${name}' publish stage failed. Error: ${e}` + ); + } + } + + print.success(`${intlMsg.commands_build_uriViewers()}:`); + print.table(uris); + + process.exitCode = 0; + }, +}; + +function validateDeployParams( + print: GluegunPrint, + params: { + manifestFile: unknown; + path: unknown; + name: unknown; + cid: unknown; + } +): boolean { + const { manifestFile, path, name, cid } = params; + + if (manifestFile === true) { + const manifestPathMissingMessage = intlMsg.commands_build_error_manifestPathMissing( + { + option: "--manifest-file", + argument: `<${pathStr}>`, + } + ); + print.error(manifestPathMissingMessage); + return false; + } + + if (path === true) { + const pathMissingMessage = intlMsg.commands_deploy_error_pathMissing({ + option: "--path", + argument: `<${pathStr}>`, + }); + print.error(pathMissingMessage); + return false; + } + + if (name === true) { + const nameMissingMessage = intlMsg.commands_deploy_error_nameMissing({ + option: "--name", + argument: `<${strStr}>`, + }); + print.error(nameMissingMessage); + return false; + } + + if (cid === true) { + const cidPathMissingMessage = intlMsg.commands_deploy_error_cidMissing({ + option: "--cid", + argument: `<${strStr}>`, + }); + print.error(cidPathMissingMessage); + return false; + } + + return true; +} From 09dfef83af22ffe87c5d50eb030ed6fbf10b51af Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 6 Apr 2022 01:11:42 +0200 Subject: [PATCH 07/41] (chore): removed deployment functionality from build command --- packages/cli/lang/en.json | 13 +- packages/cli/lang/es.json | 14 +- .../src/__tests__/project/web3api.deploy.yaml | 9 ++ packages/cli/src/commands/build.ts | 149 +----------------- packages/cli/src/lib/deploy/index.ts | 2 + packages/cli/src/lib/publishers/index.ts | 1 - packages/cli/src/lib/publishers/ipfs.ts | 39 ----- 7 files changed, 18 insertions(+), 209 deletions(-) create mode 100644 packages/cli/src/__tests__/project/web3api.deploy.yaml create mode 100644 packages/cli/src/lib/deploy/index.ts delete mode 100644 packages/cli/src/lib/publishers/index.ts delete mode 100644 packages/cli/src/lib/publishers/ipfs.ts diff --git a/packages/cli/lang/en.json b/packages/cli/lang/en.json index 390d6a9d0b..2adcbc2783 100644 --- a/packages/cli/lang/en.json +++ b/packages/cli/lang/en.json @@ -1,23 +1,12 @@ { - "commands_build_address": "ENS Address", - "commands_build_description": "Builds a Web3API and (optionally) uploads it to IPFS", - "commands_build_ensRegistry": "ENS Registry", + "commands_build_description": "Builds a Web3API", "commands_build_error_manifestPathMissing": "{option} option missing {argument} argument", "commands_build_error_manifestNotFound": "Manifest not found. Search paths used: {paths}", "commands_build_error_outputDirMissingPath": "{option} option missing {argument} argument", - "commands_build_error_resolution": "ENS Resolution Failed", - "commands_build_error_testEnsAddressMissing": "{option} option missing {argument} argument", - "commands_build_error_testEnsNodeMissing": "{option} option requires the {required} option", - "commands_build_ethProvider": "Ethereum Provider", "commands_build_keypressListener_exit": "Exit: [CTRL + C], [ESC], or [Q]", "commands_build_keypressListener_watching": "Watching", - "commands_build_options_e": "Publish the package to a test ENS domain locally (requires --ipfs)", - "commands_build_options_e_address": "address", - "commands_build_options_e_domain": "domain", "commands_build_options_h": "Show usage information", "commands_build_options_m": "Path to the Web3API Build manifest file (default: {default})", - "commands_build_options_i": "Upload build results to an IPFS node (default: dev-server's node)", - "commands_build_options_i_node": "node", "commands_build_options_o": "Output directory for build results (default: build/)", "commands_build_options_o_path": "path", "commands_build_options_options": "options", diff --git a/packages/cli/lang/es.json b/packages/cli/lang/es.json index 686f89cb4c..db9e31f949 100644 --- a/packages/cli/lang/es.json +++ b/packages/cli/lang/es.json @@ -1,23 +1,13 @@ { - "commands_build_address": "ENS Address", - "commands_build_description": "Builds a Web3API and (optionally) uploads it to IPFS", - "commands_build_ensRegistry": "ENS Registry", + "commands_build_description": "Builds a Web3API", "commands_build_error_manifestPathMissing": "{option} option missing {argument} argument", "commands_build_error_manifestNotFound": "Manifest not found. Search paths used: {paths}", "commands_build_error_outputDirMissingPath": "{option} option missing {argument} argument", - "commands_build_error_resolution": "ENS Resolution Failed", - "commands_build_error_testEnsAddressMissing": "{option} option missing {argument} argument", - "commands_build_error_testEnsNodeMissing": "{option} option requires the {required} option", - "commands_build_ethProvider": "Ethereum Provider", "commands_build_keypressListener_exit": "Exit: [CTRL + C], [ESC], or [Q]", "commands_build_keypressListener_watching": "Watching", - "commands_build_options_e": "Publish the package to a test ENS domain locally (requires --ipfs)", - "commands_build_options_e_address": "address", - "commands_build_options_e_domain": "domain", "commands_build_options_h": "Show usage information", "commands_build_options_m": "Path to the Web3API Build manifest file (default: {default})", - "commands_build_options_i": "Upload build results to an IPFS node (default: dev-server's node)", - "commands_build_options_i_node": "node", + "commands_build_options_o": "Output directory for build results (default: build/)", "commands_build_options_o_path": "path", "commands_build_options_options": "options", diff --git a/packages/cli/src/__tests__/project/web3api.deploy.yaml b/packages/cli/src/__tests__/project/web3api.deploy.yaml new file mode 100644 index 0000000000..b8c6f64178 --- /dev/null +++ b/packages/cli/src/__tests__/project/web3api.deploy.yaml @@ -0,0 +1,9 @@ +format: 0.0.1-prealpha.1 +deployments: + - name: "IPFS and ENS" + deploy: + package: + name: "@namestyd/ipfs-deployer" + versionOrPath: "npm:" + publish: + package: "npm:@namestyd/ens-publisher" diff --git a/packages/cli/src/commands/build.ts b/packages/cli/src/commands/build.ts index a10ce2b48b..992c526cae 100644 --- a/packages/cli/src/commands/build.ts +++ b/packages/cli/src/commands/build.ts @@ -6,17 +6,14 @@ import { Watcher, WatchEvent, watchEventName, - publishToIPFS, intlMsg, getDockerFileLock, defaultWeb3ApiManifest, resolvePathIfExists, - getTestEnvProviders, isDockerInstalled, } from "../lib"; import chalk from "chalk"; -import axios from "axios"; import path from "path"; import readline from "readline"; import { GluegunToolbox, GluegunPrint } from "gluegun"; @@ -24,10 +21,7 @@ import { GluegunToolbox, GluegunPrint } from "gluegun"; const defaultManifestStr = defaultWeb3ApiManifest.join(" | "); const defaultOutputDirectory = "./build"; const optionsStr = intlMsg.commands_build_options_options(); -const nodeStr = intlMsg.commands_build_options_i_node(); const pathStr = intlMsg.commands_build_options_o_path(); -const addrStr = intlMsg.commands_build_options_e_address(); -const domStr = intlMsg.commands_build_options_e_domain(); const HELP = ` ${chalk.bold("w3 build")} [${optionsStr}] @@ -37,9 +31,7 @@ ${optionsStr[0].toUpperCase() + optionsStr.slice(1)}: -m, --manifest-file <${pathStr}> ${intlMsg.commands_build_options_m({ default: defaultManifestStr, })} - -i, --ipfs [<${nodeStr}>] ${intlMsg.commands_build_options_i()} -o, --output-dir <${pathStr}> ${intlMsg.commands_build_options_o()} - -e, --test-ens <[${addrStr},]${domStr}> ${intlMsg.commands_build_options_e()} -w, --watch ${intlMsg.commands_build_options_w()} -v, --verbose ${intlMsg.commands_build_options_v()} `; @@ -51,33 +43,17 @@ export default { const { filesystem, parameters, print } = toolbox; // Options - const { h, m, i, o, w, e, v } = parameters.options; - let { - help, - manifestFile, - ipfs, - outputDir, - watch, - testEns, - verbose, - } = parameters.options; + const { h, m, o, w, v } = parameters.options; + let { help, manifestFile, outputDir, watch, verbose } = parameters.options; help = help || h; manifestFile = manifestFile || m; - ipfs = ipfs || i; outputDir = outputDir || o; watch = watch || w; - testEns = testEns || e; verbose = verbose || v; // Validate Params - const paramsValid = validateBuildParams( - print, - manifestFile, - outputDir, - testEns, - ipfs - ); + const paramsValid = validateBuildParams(print, manifestFile, outputDir); if (help || !paramsValid) { print.info(HELP); @@ -112,46 +88,6 @@ export default { (outputDir && filesystem.resolve(outputDir)) || filesystem.path(defaultOutputDirectory); - // Gather providers - let ipfsProvider: string | undefined; - let ethProvider: string | undefined; - let ensAddress: string | undefined; - let ensDomain: string | undefined; - - if (typeof ipfs === "string") { - // Custom IPFS provider - ipfsProvider = ipfs; - } else if (ipfs) { - // Try to get the dev server's IPFS & ETH providers - const testEnvProviders = await getTestEnvProviders(); - ipfsProvider = testEnvProviders.ipfsProvider; - ethProvider = testEnvProviders.ethProvider; - } - - if (typeof testEns == "string") { - // Fetch the ENS domain, and optionally the address - if (testEns.indexOf(",") > -1) { - const [addr, dom] = testEns.split(","); - ensAddress = addr; - ensDomain = dom; - } else { - ensDomain = testEns; - } - - // If not address was provided, fetch it from the server - // or deploy a new instance - if (!ensAddress) { - const getEns = await axios.get("http://localhost:4040/ens"); - - if (!getEns.data.ensAddress) { - const deployEns = await axios.get("http://localhost:4040/deploy-ens"); - ensAddress = deployEns.data.ensAddress; - } else { - ensAddress = getEns.data.ensAddress; - } - } - } - // Aquire a system-wide lock file for the docker service const dockerLock = getDockerFileLock(); @@ -164,9 +100,6 @@ export default { const schemaComposer = new SchemaComposer({ project, - ensAddress, - ethProvider, - ipfsProvider, }); const compiler = new Compiler({ @@ -183,56 +116,6 @@ export default { return result; } - const uris: string[][] = []; - - // publish to IPFS - if (ipfsProvider) { - const cid = await publishToIPFS(outputDir, ipfsProvider); - - print.success(`IPFS { ${cid} }`); - uris.push(["Web3API IPFS", `ipfs://${cid}`]); - - if (testEns) { - if (!ensAddress) { - uris.push([ - intlMsg.commands_build_ensRegistry(), - `${ethProvider}/${ensAddress}`, - ]); - } - - // ask the dev server to publish the CID to ENS - const { data } = await axios.get( - "http://localhost:4040/register-ens", - { - params: { - domain: ensDomain, - cid, - }, - } - ); - - if (data.success) { - uris.push(["Web3API ENS", `${testEns} => ${cid}`]); - } else { - print.error( - `${intlMsg.commands_build_error_resolution()} { ${testEns} => ${cid} }\n` + - `${intlMsg.commands_build_ethProvider()}: ${ethProvider}\n` + - `${intlMsg.commands_build_address()}: ${ensAddress}` - ); - } - - return data.success; - } - - if (uris.length) { - print.success(`${intlMsg.commands_build_uriViewers()}:`); - print.table(uris); - return true; - } else { - return false; - } - } - return true; }; @@ -309,9 +192,7 @@ export default { function validateBuildParams( print: GluegunPrint, manifestFile: unknown, - outputDir: unknown, - testEns: unknown, - ipfs: unknown + outputDir: unknown ): boolean { if (manifestFile === true) { const manifestPathMissingMessage = intlMsg.commands_build_error_manifestPathMissing( @@ -335,27 +216,5 @@ function validateBuildParams( return false; } - if (testEns === true) { - const testEnsAddressMissingMessage = intlMsg.commands_build_error_testEnsAddressMissing( - { - option: "--test-ens", - argument: `<[${addrStr},]${domStr}>`, - } - ); - print.error(testEnsAddressMissingMessage); - return false; - } - - if (testEns && !ipfs) { - const testEnsNodeMissingMessage = intlMsg.commands_build_error_testEnsNodeMissing( - { - option: "--test-ens", - required: `--ipfs [<${nodeStr}>]`, - } - ); - print.error(testEnsNodeMissingMessage); - return false; - } - return true; } diff --git a/packages/cli/src/lib/deploy/index.ts b/packages/cli/src/lib/deploy/index.ts new file mode 100644 index 0000000000..0a5b334860 --- /dev/null +++ b/packages/cli/src/lib/deploy/index.ts @@ -0,0 +1,2 @@ +export * from "./DeploymentManager"; +export * from "./file"; diff --git a/packages/cli/src/lib/publishers/index.ts b/packages/cli/src/lib/publishers/index.ts deleted file mode 100644 index ad08ba02d7..0000000000 --- a/packages/cli/src/lib/publishers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./ipfs"; diff --git a/packages/cli/src/lib/publishers/ipfs.ts b/packages/cli/src/lib/publishers/ipfs.ts deleted file mode 100644 index 6e85d45884..0000000000 --- a/packages/cli/src/lib/publishers/ipfs.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { intlMsg } from "../"; - -// eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires,@typescript-eslint/naming-convention -const IPFSClient = require("ipfs-http-client"); -const { globSource } = IPFSClient; - -export async function publishToIPFS( - buildPath: string, - ipfs: string -): Promise { - try { - new URL(ipfs); - } catch (e) { - const urlMalformedMessage = intlMsg.lib_publishers_ipfsPublisher_urlMalformed(); - throw Error(`${urlMalformedMessage}: ${ipfs}\n${e}`); - } - - const client = new IPFSClient(ipfs); - const globOptions = { - recursive: true, - }; - - const addOptions = { - wrapWithDirectory: false, - }; - - let rootCID = ""; - - for await (const file of client.addAll( - globSource(buildPath, globOptions), - addOptions - )) { - if (file.path.indexOf("/") === -1) { - rootCID = file.cid.toString(); - } - } - - return rootCID; -} From bbf5f42d79b5c428239a771626f8143901bf9c1f Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 6 Apr 2022 08:17:39 +0200 Subject: [PATCH 08/41] (chore): changed manifest for 1:N publishing --- .../web3api.deploy/0.0.1-prealpha.1.ts | 39 ++++--- .../formats/web3api.deploy/validate.ts | 2 +- .../web3api.deploy/0.0.1-prealpha.1.json | 109 ++++++++---------- 3 files changed, 71 insertions(+), 79 deletions(-) diff --git a/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts b/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts index 84b3246d75..786ea49d8a 100644 --- a/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts +++ b/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts @@ -8,34 +8,43 @@ export interface DeployManifest { format: "0.0.1-prealpha.1"; - deployments: { - name: string; - deploy?: { - package: { - name: string; - versionOrPath: string; - }; + deploy?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.*$". + */ + [k: string]: { + package: string; config?: { /** * This interface was referenced by `undefined`'s JSON-Schema definition * via the `patternProperty` "^.*$". */ - [k: string]: string | number; + [k: string]: unknown; }; }; - publish?: { - package: { - name: string; - versionOrPath: string; - }; + }; + publish?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.*$". + */ + [k: string]: { + package: string; config?: { /** * This interface was referenced by `undefined`'s JSON-Schema definition * via the `patternProperty` "^.*$". */ - [k: string]: string | number; + [k: string]: unknown; }; + deployment?: + | string + | { + uri: string; + }; + publish?: string; }; - }[]; + }; __type: "DeployManifest"; } diff --git a/packages/js/core/src/manifest/formats/web3api.deploy/validate.ts b/packages/js/core/src/manifest/formats/web3api.deploy/validate.ts index f8b1b3bcc3..a777599dae 100644 --- a/packages/js/core/src/manifest/formats/web3api.deploy/validate.ts +++ b/packages/js/core/src/manifest/formats/web3api.deploy/validate.ts @@ -30,7 +30,7 @@ const schemas: DeployManifestSchemas = { const validator = new Validator(); -Validator.prototype.customFormats.packageName = Validators.packageName; +Validator.prototype.customFormats.web3apiUri = Validators.web3apiUri; export const validateDeployManifest = Tracer.traceFunc( "core: validateDeployManifest", diff --git a/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json b/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json index 1eaa16f45b..20519dd606 100644 --- a/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json +++ b/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json @@ -11,75 +11,58 @@ "type": "string", "const": "0.0.1-prealpha.1" }, - "deployments": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string" + "deploy": { + "patternProperties": { + "^.*$": { + "type": "object", + "additionalProperties": false, + "properties": { + "package": { + "type": "string" + }, + "config": { + "patternProperties": { + "^.*$": { } + }, + "additionalProperties": false + } }, - "deploy": { - "type": "object", - "additionalProperties": false, - "properties": { - "package": { - "type": "object", - "properties": { - "name": { - "type" : "string", - "format": "packageName" - }, - "versionOrPath": { - "type": "string" - } - }, - "required": ["versionOrPath", "name"], - "additionalProperties": false + "required": ["package"] + } + } + }, + "publish": { + "patternProperties": { + "^.*$": { + "type": "object", + "additionalProperties": false, + "required": ["package"], + "properties": { + "package": { + "type": "string" + }, + "config": { + "patternProperties": { + "^.*$": {} }, - "config": { - "patternProperties": { - "^.*$": { - "type": ["string", "number"] - } - }, - "additionalProperties": false - } + "additionalProperties": false }, - "required": ["package"] - }, - "publish": { - "type": "object", - "additionalProperties": false, - "properties": { - "package": { - "type": "object", - "properties": { - "name": { - "type" : "string", - "format": "packageName" - }, - "versionOrPath": { - "type": "string" - } - }, - "required": ["versionOrPath", "name"], - "additionalProperties": false + "deployment": { + "type": ["string", "object"], + "properties": { + "uri": { + "type" : "string", + "format": "web3apiUri" + } }, - "config": { - "patternProperties": { - "^.*$": { - "type": ["string", "number"] - } - }, - "additionalProperties": false - } + "additionalProperties": false, + "required": ["uri"] }, - "required": ["package"] + "publish": { + "type": "string" + } } - }, - "required": ["name"] + } } } } From 9ed601e6840a7b097b0bfd064ad441b785c12d39 Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 6 Apr 2022 08:18:09 +0200 Subject: [PATCH 09/41] (chore): added IPFS deployer and ENS publisher --- packages/cli/src/lib/deployers/ipfs/index.ts | 131 ++++++++++++++++++ .../deployers/ipfs/web3api.deploy.ext.json | 20 +++ packages/cli/src/lib/publishers/ens/index.ts | 76 ++++++++++ .../publishers/ens/web3api.deploy.ext.json | 28 ++++ 4 files changed, 255 insertions(+) create mode 100644 packages/cli/src/lib/deployers/ipfs/index.ts create mode 100644 packages/cli/src/lib/deployers/ipfs/web3api.deploy.ext.json create mode 100644 packages/cli/src/lib/publishers/ens/index.ts create mode 100644 packages/cli/src/lib/publishers/ens/web3api.deploy.ext.json diff --git a/packages/cli/src/lib/deployers/ipfs/index.ts b/packages/cli/src/lib/deployers/ipfs/index.ts new file mode 100644 index 0000000000..afae937eb1 --- /dev/null +++ b/packages/cli/src/lib/deployers/ipfs/index.ts @@ -0,0 +1,131 @@ +import { Deployer } from "../../deploy/DeploymentManager"; +import { DirectoryBlob, DirectoryEntry, FileEntry } from "../../deploy/file"; + +import FormData from "form-data"; +import axios from "axios"; + +interface FormDataEntry { + key: string; + data?: string; + opts?: FormDataOptions; +} + +interface FormDataOptions { + contentType?: string; + fileName?: string; + filePath?: string; +} + +function convertDirectoryEntryToFormData( + dirs: DirectoryEntry[], + path: string +): FormDataEntry[] { + let formData: FormDataEntry[] = []; + for (let i = 0; i < dirs.length; i++) { + const dir = dirs[i]; + formData.push({ + key: dir.name, + opts: { + contentType: "application/x-directory", + fileName: encodeURIComponent(dir.name), + filePath: "", + }, + }); + const newPath = path + dir.name + "/"; + for (let j = 0; j < dir.files.length; j++) { + formData.push(convertFileEntryToFormData(dir.files[j], newPath)); + } + const rest = convertDirectoryEntryToFormData(dir.directories, newPath); + formData = formData.concat(rest); + } + return formData; +} + +function convertFileEntryToFormData( + fileEntry: FileEntry, + path: string +): FormDataEntry { + return { + key: fileEntry.name, + data: fileEntry.data, + opts: { + contentType: "application/octet-stream", + fileName: encodeURIComponent(path + fileEntry.name), + }, + }; +} + +function convertDirectoryBlobToFormData( + directoryBlob: DirectoryBlob +): FormDataEntry[] { + let formData: FormDataEntry[] = []; + const files = directoryBlob.files; + + for (let i = 0; i < files.length; i++) { + formData.push(convertFileEntryToFormData(files[i], "")); + } + + if (directoryBlob.directories.length != 0) { + const dirFormData = convertDirectoryEntryToFormData( + directoryBlob.directories, + "" + ); + formData = formData.concat(dirFormData); + } + return formData; +} + +class IPFSDeployer implements Deployer { + async deploy( + buildDirBlob: DirectoryBlob, + config?: { gatewayUri: string } + ): Promise { + console.log(`Publishing build contents to IPFS...`); + + const ipfsUrl = config?.gatewayUri ?? "https://ipfs.wrappers.io"; + + const formDataEntries = convertDirectoryBlobToFormData(buildDirBlob); + + const fd = new FormData(); + + formDataEntries.forEach((formDataEntry) => { + const options: FormData.AppendOptions = {}; + if (formDataEntry.opts) { + if ( + formDataEntry.opts.contentType && + formDataEntry.opts.contentType != "" + ) { + options.contentType = formDataEntry.opts.contentType; + } + if (formDataEntry.opts.fileName && formDataEntry.opts.fileName != "") { + options.filename = formDataEntry.opts.fileName; + } + if (formDataEntry.opts.filePath && formDataEntry.opts.filePath != "") { + options.filepath = formDataEntry.opts.filePath; + } + } + const elementData = + formDataEntry.data == null ? Buffer.alloc(0) : formDataEntry.data; + fd.append(formDataEntry.key, elementData, options); + }); + + const resp = await axios.post(`${ipfsUrl}/add`, fd, { + headers: { + ...fd.getHeaders(), + }, + }); + + if (resp.status === 200 && !resp.data.error) { + const cid = resp.data.cid; + + console.log(`Publish to IPFS successful, CID: ${cid}`); + return cid; + } else if (resp.status === 200 && resp.data.error) { + throw new Error(resp.data.error); + } else { + throw new Error("Unexpected error: " + resp.status); + } + } +} + +export default IPFSDeployer; diff --git a/packages/cli/src/lib/deployers/ipfs/web3api.deploy.ext.json b/packages/cli/src/lib/deployers/ipfs/web3api.deploy.ext.json new file mode 100644 index 0000000000..4f72267f14 --- /dev/null +++ b/packages/cli/src/lib/deployers/ipfs/web3api.deploy.ext.json @@ -0,0 +1,20 @@ +{ + "id": "DeployManifest_Deployer_WasmAsExt", + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "required": [ + "gatewayUri" + ], + "properties": { + "gatewayUri": { + "type": "string" + } + } + } + } +} \ No newline at end of file diff --git a/packages/cli/src/lib/publishers/ens/index.ts b/packages/cli/src/lib/publishers/ens/index.ts new file mode 100644 index 0000000000..0b1b8c24ad --- /dev/null +++ b/packages/cli/src/lib/publishers/ens/index.ts @@ -0,0 +1,76 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +/* eslint-disable @typescript-eslint/no-var-requires */ +import { Publisher } from "../../deploy/DeploymentManager"; + +import ethers from "ethers"; +import { namehash } from "ethers/lib/utils"; + +const contentHash = require("content-hash"); +const ENS = require("@ensdomains/ensjs"); + +const ensConfig = { + resolverAddr: + process.env.ENS_RESOLVER_ADDR ?? + "0xf6305c19e814d2a75429Fd637d01F7ee0E77d615", + resolverAbi: [ + "function contenthash(bytes32 node) external view returns (bytes memory)", + "function setContenthash(bytes32 node, bytes calldata hash) external", + "event ContenthashChanged(bytes32 indexed node, bytes hash)", + ], +}; + +class ENSPublisher implements Publisher { + blockchain = "Ethereum"; + name = "ens"; + + constructor(public network: string) {} + + async publish( + cid: string, + config: { domainName: string; provider: string; privateKey: string } + ): Promise { + console.log(`Publishing ${cid} to ${config.domainName}...`); + + const connectionProvider = new ethers.providers.JsonRpcProvider( + config.provider as string + ); + const signer = new ethers.Wallet(config.privateKey as string).connect( + connectionProvider + ); + + const network = await connectionProvider.getNetwork(); + + const ens = new ENS.default({ + provider: signer.provider, + ensAddress: ENS.getEnsAddress(network.chainId), + }); + + const ensName = ens.name(config.domainName); + const resolver = await ensName.getResolver(); + + const contract = new ethers.Contract( + resolver, + ensConfig.resolverAbi, + signer + ); + + const hash: string = "0x" + contentHash.fromIpfs(cid); + + console.log(`Setting contenthash for ${config.domainName}`); + + const tx = await contract.setContenthash( + namehash(config.domainName as string), + hash + ); + + console.log("Waiting for transaction: " + tx.hash); + + await tx.wait(); + + console.log(`Publish to "${this.network}" successful!`); + + return `Published ${cid} to ${config.domainName}`; + } +} + +export default ENSPublisher; diff --git a/packages/cli/src/lib/publishers/ens/web3api.deploy.ext.json b/packages/cli/src/lib/publishers/ens/web3api.deploy.ext.json new file mode 100644 index 0000000000..045868e6e3 --- /dev/null +++ b/packages/cli/src/lib/publishers/ens/web3api.deploy.ext.json @@ -0,0 +1,28 @@ +{ + "id": "DeployManifest_Publisher_WasmAsExt", + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "type": "object", + "required": [ + "domainName", + "provider", + "privateKey" + ], + "properties": { + "domainName": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "privateKey": { + "type": "string" + } + } + } + } +} \ No newline at end of file From 30f3fa49f40079fdd1f4a87c95f19eb27377746f Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 6 Apr 2022 08:20:50 +0200 Subject: [PATCH 10/41] (chore): added CLI env caching for deployment packages --- .../cli/src/lib/project/Web3ApiProject.ts | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/packages/cli/src/lib/project/Web3ApiProject.ts b/packages/cli/src/lib/project/Web3ApiProject.ts index c4f12e7d8e..0688e0011d 100644 --- a/packages/cli/src/lib/project/Web3ApiProject.ts +++ b/packages/cli/src/lib/project/Web3ApiProject.ts @@ -12,6 +12,7 @@ import { isWeb3ApiManifestLanguage, outputManifest, intlMsg, + loadDeployManifest, } from ".."; import { @@ -32,6 +33,8 @@ const cacheLayout = { buildEnvDir: "build/env/", buildUuidFile: "build/uuid", buildLinkedPackagesDir: "build/linked-packages/", + deployDir: "deploy/", + deployEnvDir: "deploy/env/", }; export interface Web3ApiProjectConfig extends ProjectConfig { @@ -47,6 +50,7 @@ export class Web3ApiProject extends Project { private _deployManifest: DeployManifest | undefined; private _metaManifest: MetaManifest | undefined; private _defaultBuildManifestCached = false; + private _deploymentPackagesCached = false; constructor(protected _config: Web3ApiProjectConfig) { super(_config, cacheLayout.root); @@ -60,6 +64,7 @@ export class Web3ApiProject extends Project { this._metaManifest = undefined; this._deployManifest = undefined; this._defaultBuildManifestCached = false; + this._deploymentPackagesCached = false; this.resetCache(); } @@ -366,6 +371,35 @@ export class Web3ApiProject extends Project { return this._deployManifest; } + public async cacheDeploymentPackages(packages: { + deploy: string[]; + publish: string[]; + }): Promise { + if (this._deploymentPackagesCached) { + return; + } + + this.removeCacheDir(cacheLayout.deployEnvDir); + + for await (const deployPackage of packages.deploy) { + await this.copyIntoCache( + `${cacheLayout.deployEnvDir}/${deployPackage}`, + `${__dirname}/../deployers/${deployPackage}/*`, + { up: true } + ); + } + + for await (const publishPackage of packages.publish) { + await this.copyIntoCache( + `${cacheLayout.deployEnvDir}/${publishPackage}`, + `${__dirname}/../publishers/${publishPackage}/*`, + { up: true } + ); + } + + this._deploymentPackagesCached = true; + } + /// Web3API Meta Manifest (web3api.build.yaml) public async getMetaManifestPath(): Promise { From 273f74507ddeb7c55f9b7df99cb74972a058c1a2 Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 6 Apr 2022 08:21:22 +0200 Subject: [PATCH 11/41] (feat): implemented Publisher chain of responsibility --- .../cli/src/lib/deploy/DeploymentManager.ts | 140 ++++-------------- packages/cli/src/lib/deploy/file.ts | 5 + 2 files changed, 31 insertions(+), 114 deletions(-) diff --git a/packages/cli/src/lib/deploy/DeploymentManager.ts b/packages/cli/src/lib/deploy/DeploymentManager.ts index a18315fa23..72fb0a079e 100644 --- a/packages/cli/src/lib/deploy/DeploymentManager.ts +++ b/packages/cli/src/lib/deploy/DeploymentManager.ts @@ -1,131 +1,43 @@ /* eslint-disable @typescript-eslint/no-require-imports */ -import { Web3ApiProject } from "../project"; -import { runCommand } from "../system"; -import { DirectoryEntry } from "./file"; - -import path from "path"; -import fs from "fs"; -import { DeployManifest } from "@web3api/core-js"; - -type Config = { - [k: string]: string | number; -}; +import { DirectoryBlob } from "./file"; export interface Deployer { - deploy(buildDirEntry: DirectoryEntry, config?: Config): Promise; + deploy(buildDirBlob: DirectoryBlob, config?: unknown): Promise; } export interface Publisher { - publish(cid: string, config?: Config): Promise; + publish(cid: string, config?: unknown): Promise; } -export interface Deployment { - name: string; - deployer?: Deployer; - publisher?: Publisher; - deployerConfig?: Config; - publisherConfig?: Config; +interface Handler { + addNext(handler: Handler): void; + handle(params: string): Promise; } -export class DeploymentManager { - public static readonly cacheDirName = "deployments"; - private packagesInstalled = false; - - constructor( - private project: Web3ApiProject, - private deployManifest: DeployManifest - ) {} - - public installPackages = async (deploymentName: string): Promise => { - const deploymentManifestItem = this.findDeploymentInManifest( - deploymentName - ); - - const packages: { name: string; versionOrPath: string }[] = []; - - if (deploymentManifestItem.deploy) { - packages.push(deploymentManifestItem.deploy.package); - } - - if (deploymentManifestItem.publish) { - packages.push(deploymentManifestItem.publish.package); - } - - const packageJSON = { - name: "web3api-deploy", - version: "1.0.0", - private: true, - dependencies: packages.reduce((acc, current) => { - acc[current.name] = current.versionOrPath; - return acc; - }, {} as Record), - }; - - fs.writeFileSync( - path.join( - this.project.getCachePath(DeploymentManager.cacheDirName), - "package.json" - ), - JSON.stringify(packageJSON) - ); - - await runCommand( - `cd ${this.project.getCachePath(DeploymentManager.cacheDirName)} && npm i` - ); +abstract class AbstractHandler implements Handler { + private nextHandlers: Handler[] = []; - this.packagesInstalled = true; - }; + public addNext(handler: Handler): void { + this.nextHandlers.push(handler); + } - public getDeployment = (deploymentName: string): Deployment => { - const deployment: Deployment = { - name: deploymentName, - }; - - if (!this.packagesInstalled) { - throw new Error("Packages have not been installed"); - } - - const deploymentManifestItem = this.findDeploymentInManifest( - deploymentName - ); - - const nodeModulesPath = path.join( - this.project.getCachePath(DeploymentManager.cacheDirName), - "node_modules" - ); - - if (deploymentManifestItem.deploy) { - deployment.deployer = require(path.join( - nodeModulesPath, - deploymentManifestItem.deploy.package.name - )); - - deployment.deployerConfig = deploymentManifestItem.deploy.config; + public async handle(uri: string): Promise { + const uris: string[][] = []; + for await (const handler of this.nextHandlers) { + uris.push(await handler.handle(uri)); } - if (deploymentManifestItem.publish) { - deployment.publisher = require(path.join( - nodeModulesPath, - deploymentManifestItem.publish.package.name - )); - - deployment.publisherConfig = deploymentManifestItem.publish.config; - } - - return deployment; - }; - - private findDeploymentInManifest = (deploymentName: string) => { - const deploymentManifestItem = this.deployManifest.deployments.find( - (d) => d.name === deploymentName - ); + return uris.flat(); + } +} - if (!deploymentManifestItem) { - throw new Error( - `Deployment with name '${deploymentName}' not found in manifest` - ); - } +export class PublishHandler extends AbstractHandler { + constructor(private publisher: Publisher, private config: unknown) { + super(); + } - return deploymentManifestItem; - }; + public async handle(uri: string): Promise { + const nextUri = await this.publisher.publish(uri, this.config); + return await super.handle(nextUri); + } } diff --git a/packages/cli/src/lib/deploy/file.ts b/packages/cli/src/lib/deploy/file.ts index 941db2dd16..3a7f93e086 100644 --- a/packages/cli/src/lib/deploy/file.ts +++ b/packages/cli/src/lib/deploy/file.ts @@ -1,6 +1,11 @@ import fs from "fs"; import path from "path"; +export interface DirectoryBlob { + directories: DirectoryEntry[]; + files: FileEntry[]; +} + export interface FileEntry { name: string; data: string; From 277ec460a8846de9bb3e241192f91c11c62b9aed Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 6 Apr 2022 08:22:05 +0200 Subject: [PATCH 12/41] (wip): deploy command, using publisher chain and deployment steps --- packages/cli/src/commands/deploy.ts | 162 +++++++++++++++++----------- 1 file changed, 101 insertions(+), 61 deletions(-) diff --git a/packages/cli/src/commands/deploy.ts b/packages/cli/src/commands/deploy.ts index 022dde416e..572668c5f9 100644 --- a/packages/cli/src/commands/deploy.ts +++ b/packages/cli/src/commands/deploy.ts @@ -6,17 +6,18 @@ import { defaultWeb3ApiManifest, resolvePathIfExists, } from "../lib"; -import { DeploymentManager } from "../lib/deploy/DeploymentManager"; +import { Deployer, Publisher, PublishHandler } from "../lib/deploy/DeploymentManager"; import { convertDirectoryToEntry } from "../lib/deploy/file"; import chalk from "chalk"; +import fs from "fs"; +import path from "path"; import { GluegunToolbox, GluegunPrint } from "gluegun"; const defaultManifestStr = defaultWeb3ApiManifest.join(" | "); const defaultOutputDirectory = defaultBuildPath; const optionsStr = intlMsg.commands_deploy_options_options(); const pathStr = intlMsg.commands_deploy_options_o_path(); -const strStr = intlMsg.commands_deploy_options_o_string(); const HELP = ` ${chalk.bold("w3 deploy")} [${optionsStr}] @@ -26,8 +27,6 @@ ${optionsStr[0].toUpperCase() + optionsStr.slice(1)}: -m, --manifest-file <${pathStr}> ${intlMsg.commands_deploy_options_m({ default: defaultManifestStr, })} - -n, --name <${strStr}> ${intlMsg.commands_deploy_options_n()} - -c, --cid <${strStr}> ${intlMsg.commands_deploy_options_c()} -v, --verbose ${intlMsg.commands_deploy_options_v()} -p, --path [<${pathStr}>]" ${intlMsg.commands_deploy_options_p()} `; @@ -96,56 +95,82 @@ export default { throw new Error("No deploy manifest"); } - const deploymentManager = new DeploymentManager(project, deployManifest); + const packages = { + deploy: deployManifest.deploy + ? Object.values(deployManifest.deploy).map((d) => d.package) + : [], + publish: deployManifest.publish + ? Object.values(deployManifest.publish).map((p) => p.package) + : [], + }; - await deploymentManager.installPackages(name); + sanitizePackages(packages); - const deployment = deploymentManager.getDeployment(name); + await project.cacheDeploymentPackages(packages); - if (!deployment.deployer && !cid) { - throw new Error( - `No deploy stage is present in deployment '${name}', a cid arg is required for publish` - ); - } + const deployments: Record = {}; - const uris: string[][] = []; - let deployResult: string | undefined; - let publishResult: string | undefined; - - if (deployment.deployer) { + // Deploy steps don't depend on anything. Execute them all + if (deployManifest.deploy) { const buildDirEntry = convertDirectoryToEntry(buildPath); - try { - deployResult = await deployment.deployer.deploy( - buildDirEntry, - deployment.deployerConfig - ); - - uris.push(["Deploy", deployResult]); - } catch (e) { - throw new Error( - `Deployment '${name}' deploy stage failed. Error: ${e}` - ); + for await (const key of Object.keys(deployManifest.deploy)) { + const deployer = getDeployer(key); + + const uri = await deployer.deploy({ + files: [], + directories: [buildDirEntry], + }); + + deployments[key] = uri; } + + console.log(deployments); } - if (deployment.publisher) { - try { - publishResult = await deployment.publisher.publish( - deployResult ?? cid, - deployment.deployerConfig - ); - - uris.push(["Publish", publishResult]); - } catch (e) { - throw new Error( - `Deployment '${name}' publish stage failed. Error: ${e}` - ); + if (deployManifest.publish) { + const handlers: Record = {}; + const roots: { handler: PublishHandler; uri: string }[] = []; + + // Create all handlers + Object.entries(deployManifest.publish).forEach(([key, value]) => { + const publisher = getPublisher(value.package); + const handler = new PublishHandler(publisher, value.config); + + handlers[key] = handler; + }); + + // Establish dependency chains + Object.entries(deployManifest.publish).forEach(([key, value]) => { + const thisHandler = handlers[key]; + + if (value.publish) { + // Depends on other publish step + handlers[value.publish].addNext(thisHandler); + } else if (typeof value.deployment === "string") { + // Depends on deploy step + roots.push({ + uri: deployments[value.deployment], + handler: thisHandler, + }); + } else if (typeof value.deployment === "object") { + // It is a root node + roots.push({ uri: value.deployment.uri, handler: thisHandler }); + } else { + throw new Error("Needs either previous step or URI"); + } + }); + + // Execute roots + + const uris: string[][] = []; + + for await (const root of roots) { + uris.push(await root.handler.handle(root.uri)); } - } - print.success(`${intlMsg.commands_build_uriViewers()}:`); - print.table(uris); + print.table(uris); + } process.exitCode = 0; }, @@ -160,7 +185,7 @@ function validateDeployParams( cid: unknown; } ): boolean { - const { manifestFile, path, name, cid } = params; + const { manifestFile, path } = params; if (manifestFile === true) { const manifestPathMissingMessage = intlMsg.commands_build_error_manifestPathMissing( @@ -182,23 +207,38 @@ function validateDeployParams( return false; } - if (name === true) { - const nameMissingMessage = intlMsg.commands_deploy_error_nameMissing({ - option: "--name", - argument: `<${strStr}>`, - }); - print.error(nameMissingMessage); - return false; - } + return true; +} - if (cid === true) { - const cidPathMissingMessage = intlMsg.commands_deploy_error_cidMissing({ - option: "--cid", - argument: `<${strStr}>`, - }); - print.error(cidPathMissingMessage); - return false; - } +function sanitizePackages(packages: { deploy: string[]; publish: string[] }) { + const unrecognizedPackages: string[] = []; - return true; + const availableDeployers = fs.readdirSync( + path.join(__dirname, "..", "deployers") + ); + + const availablePublishers = fs.readdirSync( + path.join(__dirname, "..", "publishers") + ); + + packages.deploy.forEach((p) => { + if (!availableDeployers.includes(p)) { + unrecognizedPackages.push(p); + } + }); + + packages.publish.forEach((p) => { + if (!availablePublishers.includes(p)) { + unrecognizedPackages.push(p); + } + }); + + if (unrecognizedPackages.length) { + throw new Error( + `Unrecognized packages: ${unrecognizedPackages.join(", ")}` + ); + } } + +function getPublisher(name: string): Publisher {} +function getDeployer(name: string): Deployer {} From 8f81a99df9e90dce558fcaba22f0f9a60eb93d2d Mon Sep 17 00:00:00 2001 From: namesty Date: Tue, 12 Apr 2022 06:08:06 +0200 Subject: [PATCH 13/41] (feat): modified steps into agnostic stages. Print methods. Working --- packages/cli/src/__tests__/e2e/deploy.spec.ts | 151 +++++++++++++++++ .../src/__tests__/project/web3api.deploy.yaml | 33 +++- .../cli/src/__tests__/project/web3api.yaml | 3 +- packages/cli/src/commands/deploy.ts | 153 ++++++------------ .../cli/src/lib/deploy/DeploymentManager.ts | 43 ----- packages/cli/src/lib/deploy/deployer.ts | 73 +++++++++ packages/cli/src/lib/deploy/index.ts | 3 +- packages/cli/src/lib/deployers/ens/index.ts | 78 +++++++++ .../ens/web3api.deploy.ext.json | 2 +- .../lib/{deploy => deployers/ipfs}/file.ts | 0 .../cli/src/lib/deployers/ipfs/formData.ts | 74 +++++++++ packages/cli/src/lib/deployers/ipfs/index.ts | 112 ++++--------- packages/cli/src/lib/deployers/ipfs/utils.ts | 27 ++++ packages/cli/src/lib/index.ts | 2 +- .../cli/src/lib/project/Web3ApiProject.ts | 30 ++-- packages/cli/src/lib/publishers/ens/index.ts | 76 --------- .../web3api.deploy/0.0.1-prealpha.1.ts | 26 +-- .../web3api.deploy/0.0.1-prealpha.1.json | 41 +---- 18 files changed, 539 insertions(+), 388 deletions(-) create mode 100644 packages/cli/src/__tests__/e2e/deploy.spec.ts delete mode 100644 packages/cli/src/lib/deploy/DeploymentManager.ts create mode 100644 packages/cli/src/lib/deploy/deployer.ts create mode 100644 packages/cli/src/lib/deployers/ens/index.ts rename packages/cli/src/lib/{publishers => deployers}/ens/web3api.deploy.ext.json (90%) rename packages/cli/src/lib/{deploy => deployers/ipfs}/file.ts (100%) create mode 100644 packages/cli/src/lib/deployers/ipfs/formData.ts create mode 100644 packages/cli/src/lib/deployers/ipfs/utils.ts delete mode 100644 packages/cli/src/lib/publishers/ens/index.ts diff --git a/packages/cli/src/__tests__/e2e/deploy.spec.ts b/packages/cli/src/__tests__/e2e/deploy.spec.ts new file mode 100644 index 0000000000..18db8da712 --- /dev/null +++ b/packages/cli/src/__tests__/e2e/deploy.spec.ts @@ -0,0 +1,151 @@ +import { clearStyle, w3Cli } from "./utils"; + +import { + initTestEnvironment, + runCLI, stopTestEnvironment, +} from "@web3api/test-env-js"; +import path from "path"; +import axios from "axios"; +import { DeployManifest, Web3ApiClient } from "@web3api/client-js"; +import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; +import { keccak256 } from "js-sha3"; +import { Wallet } from "ethers"; +import { namehash } from "ethers/lib/utils"; +import yaml from "js-yaml"; +import fs from "fs"; + +const projectRoot = path.resolve(__dirname, "../project/"); + +const HELP = ` +w3 deploy [options] + +Options: + -h, --help Show usage information + -m, --manifest-file Path to the Web3API Deploy manifest file (default: web3api.yaml | web3api.yml) + -v, --verbose Verbose output (default: false) + -p, --path Path to the build directory +`; + +const setup = async (domainNames: string[]) => { + const { ethereum } = await initTestEnvironment(); + const { data } = await axios.get("http://localhost:4040/deploy-ens"); + + const ensAddress = data.ensAddress + const resolverAddress = data.resolverAddress + const registrarAddress = data.registrarAddress + const signer = new Wallet("0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"); + + const deployManifest = yaml.load( + await fs.promises.readFile( + `${projectRoot}/web3api.deploy.yaml`, + "utf8" + ) + ) as DeployManifest; + + Object.entries(deployManifest.stages).forEach(([key, value]) => { + if (value.config && value.config.ensRegistryAddress) { + deployManifest.stages[key].config!.ensRegistryAddress = ensAddress; + } + }) + + await fs.promises.writeFile( + `${projectRoot}/web3api.deploy.yaml`, + yaml.dump(deployManifest) + ) + + const client = new Web3ApiClient({ + plugins: [ + { + uri: "w3://ens/ethereum.web3api.eth", + plugin: ethereumPlugin({ + networks: { + testnet: { + provider: ethereum, + signer + } + }, + defaultNetwork: "testnet" + }), + } + ], + }); + + for await (const domainName of domainNames) { + const label = "0x" + keccak256(domainName) + await client.query({ + uri: "w3://ens/ethereum.web3api.eth", + query: ` + mutation { + callContractMethodAndWait( + address: "${registrarAddress}", + method: "function register(bytes32 label, address owner)", + args: ["${label}", "${signer.address}"], + txOverrides: { + value: null, + nonce: null, + gasPrice: "50", + gasLimit: "200000" + } + ) + } + `, + }); + + await client.query({ + uri: "w3://ens/ethereum.web3api.eth", + query: ` + mutation { + callContractMethod( + address: "${ensAddress}", + method: "function setResolver(bytes32 node, address owner)", + args: ["${namehash(`${domainName}.eth`)}", "${resolverAddress}"] + ) + } + ` + }); + } +} + +describe("e2e tests for deploy command", () => { + beforeAll(async () => { + await setup(["test1", "test2", "test3"]) + await runCLI( + { + args: ["build", "-v"], + cwd: projectRoot, + cli: w3Cli, + }, + ); + }) + + afterAll(async () => { + await stopTestEnvironment(); + }) + + test("Should show help text", async () => { + const { exitCode: code, stdout: output, stderr: error } = await runCLI( + { + args: ["deploy", "--help"], + cwd: projectRoot, + cli: w3Cli, + }, + ); + + expect(code).toEqual(0); + expect(error).toBe(""); + expect(clearStyle(output)).toEqual(HELP); + }); + + test.only("Successfully deploys the project", async () => { + const { stdout: output, stderr: error } = await runCLI( + { + args: ["deploy"], + cwd: projectRoot, + cli: w3Cli, + }, + ); + + console.log(output) + console.log(error) + }); +}); diff --git a/packages/cli/src/__tests__/project/web3api.deploy.yaml b/packages/cli/src/__tests__/project/web3api.deploy.yaml index b8c6f64178..283fabcd22 100644 --- a/packages/cli/src/__tests__/project/web3api.deploy.yaml +++ b/packages/cli/src/__tests__/project/web3api.deploy.yaml @@ -1,9 +1,26 @@ format: 0.0.1-prealpha.1 -deployments: - - name: "IPFS and ENS" - deploy: - package: - name: "@namestyd/ipfs-deployer" - versionOrPath: "npm:" - publish: - package: "npm:@namestyd/ens-publisher" +stages: + ipfs_deploy: + package: ipfs + uri: file/./build + from_deploy: + package: ens + depends_on: ipfs_deploy + config: + domainName: test1.eth + provider: 'http://localhost:8545' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' + from_deploy2: + package: ens + depends_on: ipfs_deploy + config: + domainName: test2.eth + provider: 'http://localhost:8545' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' + from_uri: + package: ens + uri: ipfs/QmVdDR6QtigTt38Xwpj2Ki73X1AyZn5WRCreBCJq1CEtpF + config: + domainName: test3.eth + provider: 'http://localhost:8545' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' diff --git a/packages/cli/src/__tests__/project/web3api.yaml b/packages/cli/src/__tests__/project/web3api.yaml index e7880e1e3a..71775fc838 100644 --- a/packages/cli/src/__tests__/project/web3api.yaml +++ b/packages/cli/src/__tests__/project/web3api.yaml @@ -1,6 +1,7 @@ -format: 0.0.1-prealpha.7 +format: 0.0.1-prealpha.8 name: test-project build: ./web3api.build.yaml +deploy: ./web3api.deploy.yaml language: wasm/assemblyscript modules: mutation: diff --git a/packages/cli/src/commands/deploy.ts b/packages/cli/src/commands/deploy.ts index 572668c5f9..5de79b3d62 100644 --- a/packages/cli/src/commands/deploy.ts +++ b/packages/cli/src/commands/deploy.ts @@ -1,21 +1,19 @@ /* eslint-disable prefer-const */ import { intlMsg, - defaultBuildPath, Web3ApiProject, defaultWeb3ApiManifest, resolvePathIfExists, } from "../lib"; -import { Deployer, Publisher, PublishHandler } from "../lib/deploy/DeploymentManager"; -import { convertDirectoryToEntry } from "../lib/deploy/file"; +import { DeployerHandler } from "../lib/deploy/deployer"; import chalk from "chalk"; import fs from "fs"; -import path from "path"; +import nodePath from "path"; import { GluegunToolbox, GluegunPrint } from "gluegun"; +import { Uri } from "@web3api/core-js"; const defaultManifestStr = defaultWeb3ApiManifest.join(" | "); -const defaultOutputDirectory = defaultBuildPath; const optionsStr = intlMsg.commands_deploy_options_options(); const pathStr = intlMsg.commands_deploy_options_o_path(); @@ -24,11 +22,10 @@ ${chalk.bold("w3 deploy")} [${optionsStr}] ${optionsStr[0].toUpperCase() + optionsStr.slice(1)}: -h, --help ${intlMsg.commands_deploy_options_h()} - -m, --manifest-file <${pathStr}> ${intlMsg.commands_deploy_options_m({ + -m, --manifest-file <${pathStr}> ${intlMsg.commands_deploy_options_m({ default: defaultManifestStr, })} -v, --verbose ${intlMsg.commands_deploy_options_v()} - -p, --path [<${pathStr}>]" ${intlMsg.commands_deploy_options_p()} `; export default { @@ -38,11 +35,10 @@ export default { const { filesystem, parameters, print } = toolbox; // Options - const { h, p, m, v, n, c } = parameters.options; - let { help, path, manifestFile, verbose, name, cid } = parameters.options; + const { h, m, v, n, c } = parameters.options; + let { help, manifestFile, verbose, name, cid } = parameters.options; help = help || h; - path = path || p; verbose = verbose || v; manifestFile = manifestFile || m; name = name || n; @@ -52,7 +48,6 @@ export default { const paramsValid = validateDeployParams(print, { name, cid, - path, manifestFile, }); @@ -79,10 +74,8 @@ export default { return; } - const buildPath: string = path ?? defaultOutputDirectory; - const project = new Web3ApiProject({ - rootCacheDir: path.dirname(manifestFile), + rootCacheDir: nodePath.dirname(manifestFile), web3apiManifestPath: manifestFile, quiet: verbose ? false : true, }); @@ -95,83 +88,58 @@ export default { throw new Error("No deploy manifest"); } - const packages = { - deploy: deployManifest.deploy - ? Object.values(deployManifest.deploy).map((d) => d.package) - : [], - publish: deployManifest.publish - ? Object.values(deployManifest.publish).map((p) => p.package) - : [], - }; + const packages = Object.values(deployManifest.stages).map((d) => d.package); sanitizePackages(packages); await project.cacheDeploymentPackages(packages); - const deployments: Record = {}; - - // Deploy steps don't depend on anything. Execute them all - if (deployManifest.deploy) { - const buildDirEntry = convertDirectoryToEntry(buildPath); + const handlers: Record = {}; + const roots: { handler: DeployerHandler; uri: Uri }[] = []; - for await (const key of Object.keys(deployManifest.deploy)) { - const deployer = getDeployer(key); + // Create all handlers + Object.entries(deployManifest.stages).forEach(([key, value]) => { + const publisher = project.getDeploymentPackage(value.package); + const handler = new DeployerHandler(key, publisher, value.config); - const uri = await deployer.deploy({ - files: [], - directories: [buildDirEntry], - }); + handlers[key] = handler; + }); - deployments[key] = uri; + // Establish dependency chains + Object.entries(deployManifest.stages).forEach(([key, value]) => { + const thisHandler = handlers[key]; + + if (value.depends_on) { + // Depends on another stage + handlers[value.depends_on].addNext(thisHandler); + } else if (value.uri) { + // It is a root node + roots.push({ uri: new Uri(value.uri), handler: thisHandler }); + } else { + throw new Error( + `Stage '${key}' needs either previous (depends_on) stage or URI` + ); } + }); - console.log(deployments); - } + // Execute roots - if (deployManifest.publish) { - const handlers: Record = {}; - const roots: { handler: PublishHandler; uri: string }[] = []; - - // Create all handlers - Object.entries(deployManifest.publish).forEach(([key, value]) => { - const publisher = getPublisher(value.package); - const handler = new PublishHandler(publisher, value.config); - - handlers[key] = handler; - }); - - // Establish dependency chains - Object.entries(deployManifest.publish).forEach(([key, value]) => { - const thisHandler = handlers[key]; - - if (value.publish) { - // Depends on other publish step - handlers[value.publish].addNext(thisHandler); - } else if (typeof value.deployment === "string") { - // Depends on deploy step - roots.push({ - uri: deployments[value.deployment], - handler: thisHandler, - }); - } else if (typeof value.deployment === "object") { - // It is a root node - roots.push({ uri: value.deployment.uri, handler: thisHandler }); - } else { - throw new Error("Needs either previous step or URI"); - } - }); - - // Execute roots - - const uris: string[][] = []; - - for await (const root of roots) { - uris.push(await root.handler.handle(root.uri)); - } + roots.forEach((root) => { + console.log(root.handler.getList()); + }); + + const uris: Uri[][] = []; - print.table(uris); + for await (const root of roots) { + uris.push(await root.handler.handle(root.uri)); } + roots.forEach((root) => { + console.log(root.handler.getResultsList()); + }); + + console.log(uris.map((uArray) => uArray.map((u) => u.toString()))); + process.exitCode = 0; }, }; @@ -180,12 +148,11 @@ function validateDeployParams( print: GluegunPrint, params: { manifestFile: unknown; - path: unknown; name: unknown; cid: unknown; } ): boolean { - const { manifestFile, path } = params; + const { manifestFile } = params; if (manifestFile === true) { const manifestPathMissingMessage = intlMsg.commands_build_error_manifestPathMissing( @@ -198,47 +165,25 @@ function validateDeployParams( return false; } - if (path === true) { - const pathMissingMessage = intlMsg.commands_deploy_error_pathMissing({ - option: "--path", - argument: `<${pathStr}>`, - }); - print.error(pathMissingMessage); - return false; - } - return true; } -function sanitizePackages(packages: { deploy: string[]; publish: string[] }) { +function sanitizePackages(packages: string[]) { const unrecognizedPackages: string[] = []; const availableDeployers = fs.readdirSync( - path.join(__dirname, "..", "deployers") - ); - - const availablePublishers = fs.readdirSync( - path.join(__dirname, "..", "publishers") + nodePath.join(__dirname, "..", "lib", "deployers") ); - packages.deploy.forEach((p) => { + packages.forEach((p) => { if (!availableDeployers.includes(p)) { unrecognizedPackages.push(p); } }); - packages.publish.forEach((p) => { - if (!availablePublishers.includes(p)) { - unrecognizedPackages.push(p); - } - }); - if (unrecognizedPackages.length) { throw new Error( `Unrecognized packages: ${unrecognizedPackages.join(", ")}` ); } } - -function getPublisher(name: string): Publisher {} -function getDeployer(name: string): Deployer {} diff --git a/packages/cli/src/lib/deploy/DeploymentManager.ts b/packages/cli/src/lib/deploy/DeploymentManager.ts deleted file mode 100644 index 72fb0a079e..0000000000 --- a/packages/cli/src/lib/deploy/DeploymentManager.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* eslint-disable @typescript-eslint/no-require-imports */ -import { DirectoryBlob } from "./file"; - -export interface Deployer { - deploy(buildDirBlob: DirectoryBlob, config?: unknown): Promise; -} - -export interface Publisher { - publish(cid: string, config?: unknown): Promise; -} - -interface Handler { - addNext(handler: Handler): void; - handle(params: string): Promise; -} - -abstract class AbstractHandler implements Handler { - private nextHandlers: Handler[] = []; - - public addNext(handler: Handler): void { - this.nextHandlers.push(handler); - } - - public async handle(uri: string): Promise { - const uris: string[][] = []; - for await (const handler of this.nextHandlers) { - uris.push(await handler.handle(uri)); - } - - return uris.flat(); - } -} - -export class PublishHandler extends AbstractHandler { - constructor(private publisher: Publisher, private config: unknown) { - super(); - } - - public async handle(uri: string): Promise { - const nextUri = await this.publisher.publish(uri, this.config); - return await super.handle(nextUri); - } -} diff --git a/packages/cli/src/lib/deploy/deployer.ts b/packages/cli/src/lib/deploy/deployer.ts new file mode 100644 index 0000000000..f492970eb7 --- /dev/null +++ b/packages/cli/src/lib/deploy/deployer.ts @@ -0,0 +1,73 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +import { Uri } from "@web3api/core-js"; + +export interface Deployer { + execute(uri: Uri, config?: unknown): Promise; +} + +interface List { + name: string; + children: List[]; +} + +interface ResultList { + name: string; + result: string; + children: ResultList[]; +} + +interface Handler { + addNext(handler: Handler): void; + handle(params: Uri): Promise; +} + +abstract class AbstractHandler implements Handler { + private nextHandlers: AbstractHandler[] = []; + protected result: string; + + constructor(public name: string) {} + + public addNext(handler: AbstractHandler): void { + this.nextHandlers.push(handler); + } + + public async handle(uri: Uri): Promise { + const uris: Uri[][] = []; + for await (const handler of this.nextHandlers) { + uris.push(await handler.handle(uri)); + } + + return uris.flat(); + } + + public getList(): List { + return { + name: this.name, + children: this.nextHandlers.map((n) => n.getList()), + }; + } + + public getResultsList(): ResultList { + return { + name: this.name, + result: this.result, + children: this.nextHandlers.map((n) => n.getResultsList()), + }; + } +} + +export class DeployerHandler extends AbstractHandler { + constructor( + name: string, + private deployer: Deployer, + private config: unknown + ) { + super(name); + } + + public async handle(uri: Uri): Promise { + const nextUri = await this.deployer.execute(uri, this.config); + this.result = nextUri.toString(); + return [nextUri, ...(await super.handle(nextUri))]; + } +} diff --git a/packages/cli/src/lib/deploy/index.ts b/packages/cli/src/lib/deploy/index.ts index 0a5b334860..abb67ce8cd 100644 --- a/packages/cli/src/lib/deploy/index.ts +++ b/packages/cli/src/lib/deploy/index.ts @@ -1,2 +1 @@ -export * from "./DeploymentManager"; -export * from "./file"; +export * from "./deployer"; diff --git a/packages/cli/src/lib/deployers/ens/index.ts b/packages/cli/src/lib/deployers/ens/index.ts new file mode 100644 index 0000000000..17d17c86b2 --- /dev/null +++ b/packages/cli/src/lib/deployers/ens/index.ts @@ -0,0 +1,78 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +/* eslint-disable @typescript-eslint/no-var-requires */ +import { Deployer } from "../../deploy/deployer"; + +import { ethers } from "ethers"; +import { namehash } from "ethers/lib/utils"; +import { Uri } from "@web3api/core-js"; + +const contentHash = require("content-hash"); +const ENS = require("@ensdomains/ensjs"); + +class ENSPublisher implements Deployer { + blockchain = "Ethereum"; + name = "ens"; + + async execute( + uri: Uri, + config: { + domainName: string; + provider: string; + privateKey?: string; + ensRegistryAddress: string; + } + ): Promise { + if (uri.authority !== "ipfs") { + throw new Error( + `ENS Deployer: resolved URI from ${uri} does not represent an IPFS contentHash` + ); + } + + const cid = uri.path; + + const connectionProvider = new ethers.providers.JsonRpcProvider( + config.provider as string + ); + + let signer: ethers.Signer; + + if (config.privateKey) { + signer = new ethers.Wallet(config.privateKey as string).connect( + connectionProvider + ); + } else { + signer = connectionProvider.getSigner(0); + } + + const ens = new ENS.default({ + provider: connectionProvider, + ensAddress: config.ensRegistryAddress, + }); + + const ensName = ens.name(config.domainName); + const resolver = await ensName.getResolver(); + + const contract = new ethers.Contract( + resolver, + [ + "function contenthash(bytes32 node) external view returns (bytes memory)", + "function setContenthash(bytes32 node, bytes calldata hash) external", + "event ContenthashChanged(bytes32 indexed node, bytes hash)", + ], + signer + ); + + const hash: string = "0x" + contentHash.fromIpfs(cid); + + const tx = await contract.setContenthash( + namehash(config.domainName as string), + hash + ); + + await tx.wait(); + + return new Uri(`ens/${config.domainName}`); + } +} + +export default new ENSPublisher(); diff --git a/packages/cli/src/lib/publishers/ens/web3api.deploy.ext.json b/packages/cli/src/lib/deployers/ens/web3api.deploy.ext.json similarity index 90% rename from packages/cli/src/lib/publishers/ens/web3api.deploy.ext.json rename to packages/cli/src/lib/deployers/ens/web3api.deploy.ext.json index 045868e6e3..baf39908a0 100644 --- a/packages/cli/src/lib/publishers/ens/web3api.deploy.ext.json +++ b/packages/cli/src/lib/deployers/ens/web3api.deploy.ext.json @@ -1,5 +1,5 @@ { - "id": "DeployManifest_Publisher_WasmAsExt", + "id": "DeployManifest_ENS_WasmAsExt", "type": "object", "required": [ "config" diff --git a/packages/cli/src/lib/deploy/file.ts b/packages/cli/src/lib/deployers/ipfs/file.ts similarity index 100% rename from packages/cli/src/lib/deploy/file.ts rename to packages/cli/src/lib/deployers/ipfs/file.ts diff --git a/packages/cli/src/lib/deployers/ipfs/formData.ts b/packages/cli/src/lib/deployers/ipfs/formData.ts new file mode 100644 index 0000000000..48efd8b2d4 --- /dev/null +++ b/packages/cli/src/lib/deployers/ipfs/formData.ts @@ -0,0 +1,74 @@ +import { DirectoryBlob, DirectoryEntry, FileEntry } from "./file"; + +interface FormDataEntry { + key: string; + data?: string; + opts?: FormDataOptions; +} + +interface FormDataOptions { + contentType?: string; + fileName?: string; + filePath?: string; +} + +function convertDirectoryEntryToFormData( + dirs: DirectoryEntry[], + path: string +): FormDataEntry[] { + let formData: FormDataEntry[] = []; + for (let i = 0; i < dirs.length; i++) { + const dir = dirs[i]; + formData.push({ + key: dir.name, + opts: { + contentType: "application/x-directory", + fileName: encodeURIComponent(dir.name), + filePath: "", + }, + }); + const newPath = path + dir.name + "/"; + for (let j = 0; j < dir.files.length; j++) { + formData.push(convertFileEntryToFormData(dir.files[j], newPath)); + } + const rest = convertDirectoryEntryToFormData(dir.directories, newPath); + formData = formData.concat(rest); + } + return formData; +} + +function convertFileEntryToFormData( + fileEntry: FileEntry, + path: string +): FormDataEntry { + return { + key: fileEntry.name, + data: fileEntry.data, + opts: { + contentType: "application/octet-stream", + fileName: encodeURIComponent(path + fileEntry.name), + }, + }; +} + +export function convertDirectoryBlobToFormData( + directoryBlob: DirectoryBlob +): FormDataEntry[] { + let formData: FormDataEntry[] = []; + const files = directoryBlob.files; + + console.log(files.map((f) => f.name)); + + for (let i = 0; i < files.length; i++) { + formData.push(convertFileEntryToFormData(files[i], "")); + } + + if (directoryBlob.directories.length != 0) { + const dirFormData = convertDirectoryEntryToFormData( + directoryBlob.directories, + "" + ); + formData = formData.concat(dirFormData); + } + return formData; +} diff --git a/packages/cli/src/lib/deployers/ipfs/index.ts b/packages/cli/src/lib/deployers/ipfs/index.ts index afae937eb1..b7d86d7c6c 100644 --- a/packages/cli/src/lib/deployers/ipfs/index.ts +++ b/packages/cli/src/lib/deployers/ipfs/index.ts @@ -1,88 +1,33 @@ -import { Deployer } from "../../deploy/DeploymentManager"; -import { DirectoryBlob, DirectoryEntry, FileEntry } from "../../deploy/file"; +import { Deployer } from "../../deploy/deployer"; +import { convertDirectoryBlobToFormData } from "./formData"; +import { parseAddDirectoryResponse } from "./utils"; +import { convertDirectoryToEntry, DirectoryBlob } from "./file"; import FormData from "form-data"; import axios from "axios"; +import { Uri } from "@web3api/core-js"; -interface FormDataEntry { - key: string; - data?: string; - opts?: FormDataOptions; -} - -interface FormDataOptions { - contentType?: string; - fileName?: string; - filePath?: string; -} +const isValidUri = (uri: Uri) => uri.authority === "file"; -function convertDirectoryEntryToFormData( - dirs: DirectoryEntry[], - path: string -): FormDataEntry[] { - let formData: FormDataEntry[] = []; - for (let i = 0; i < dirs.length; i++) { - const dir = dirs[i]; - formData.push({ - key: dir.name, - opts: { - contentType: "application/x-directory", - fileName: encodeURIComponent(dir.name), - filePath: "", - }, - }); - const newPath = path + dir.name + "/"; - for (let j = 0; j < dir.files.length; j++) { - formData.push(convertFileEntryToFormData(dir.files[j], newPath)); - } - const rest = convertDirectoryEntryToFormData(dir.directories, newPath); - formData = formData.concat(rest); - } - return formData; -} +const resolveBuildDir = (path: string): DirectoryBlob => { + const dirEntry = convertDirectoryToEntry(path); -function convertFileEntryToFormData( - fileEntry: FileEntry, - path: string -): FormDataEntry { return { - key: fileEntry.name, - data: fileEntry.data, - opts: { - contentType: "application/octet-stream", - fileName: encodeURIComponent(path + fileEntry.name), - }, + files: [], + directories: [dirEntry], }; -} - -function convertDirectoryBlobToFormData( - directoryBlob: DirectoryBlob -): FormDataEntry[] { - let formData: FormDataEntry[] = []; - const files = directoryBlob.files; - - for (let i = 0; i < files.length; i++) { - formData.push(convertFileEntryToFormData(files[i], "")); - } - - if (directoryBlob.directories.length != 0) { - const dirFormData = convertDirectoryEntryToFormData( - directoryBlob.directories, - "" - ); - formData = formData.concat(dirFormData); - } - return formData; -} +}; class IPFSDeployer implements Deployer { - async deploy( - buildDirBlob: DirectoryBlob, - config?: { gatewayUri: string } - ): Promise { - console.log(`Publishing build contents to IPFS...`); + async execute(uri: Uri, config?: { gatewayUri: string }): Promise { + if (!isValidUri(uri)) { + throw new Error("Invalid URI"); + } + + const path = uri.path; + const buildDirBlob = resolveBuildDir(path); - const ipfsUrl = config?.gatewayUri ?? "https://ipfs.wrappers.io"; + const ipfsUrl = config?.gatewayUri ?? "http://localhost:5001"; const formDataEntries = convertDirectoryBlobToFormData(buildDirBlob); @@ -109,23 +54,26 @@ class IPFSDeployer implements Deployer { fd.append(formDataEntry.key, elementData, options); }); - const resp = await axios.post(`${ipfsUrl}/add`, fd, { + const resp = await axios.post(`${ipfsUrl}/api/v0/add`, fd, { headers: { ...fd.getHeaders(), }, }); - if (resp.status === 200 && !resp.data.error) { - const cid = resp.data.cid; + if (resp.status === 200) { + const directoryCID = parseAddDirectoryResponse(resp.data).find( + (a) => !a.name.includes("/") + )?.hash; + + if (!directoryCID) { + throw new Error("Could not find root folder's CID"); + } - console.log(`Publish to IPFS successful, CID: ${cid}`); - return cid; - } else if (resp.status === 200 && resp.data.error) { - throw new Error(resp.data.error); + return new Uri(`ipfs/${directoryCID}`); } else { throw new Error("Unexpected error: " + resp.status); } } } -export default IPFSDeployer; +export default new IPFSDeployer(); diff --git a/packages/cli/src/lib/deployers/ipfs/utils.ts b/packages/cli/src/lib/deployers/ipfs/utils.ts new file mode 100644 index 0000000000..a3742aef2a --- /dev/null +++ b/packages/cli/src/lib/deployers/ipfs/utils.ts @@ -0,0 +1,27 @@ +export interface AddResult { + name: string; + hash: string; + size: string; +} + +export function parseAddDirectoryResponse(body: string): AddResult[] { + const results: AddResult[] = []; + const rawResults = body.split("\n"); + for (let i = 0; i < rawResults.length - 1; i++) { + const parsedResult = parseAddResponse(rawResults[i]); + results.push(parsedResult); + } + return results; +} + +function parseAddResponse(body: string): AddResult { + const addResult: AddResult = { name: "", hash: "", size: "" }; + if (body != null) { + const responseObj = JSON.parse(body); + + addResult.name = responseObj["Name"]; + addResult.hash = responseObj["Hash"]; + addResult.size = responseObj["Size"]; + } + return addResult; +} diff --git a/packages/cli/src/lib/index.ts b/packages/cli/src/lib/index.ts index d419c3d23c..54443a6a63 100644 --- a/packages/cli/src/lib/index.ts +++ b/packages/cli/src/lib/index.ts @@ -2,8 +2,8 @@ export * from "./helpers"; export * from "./intl"; export * from "./manifest"; export * from "./project"; +export * from "./deploy"; export * from "./project-templates"; -export * from "./publishers"; export * from "./system"; export * from "./test-env"; export * from "./Compiler"; diff --git a/packages/cli/src/lib/project/Web3ApiProject.ts b/packages/cli/src/lib/project/Web3ApiProject.ts index 0688e0011d..df5bc36dbf 100644 --- a/packages/cli/src/lib/project/Web3ApiProject.ts +++ b/packages/cli/src/lib/project/Web3ApiProject.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/naming-convention */ import { ProjectConfig, Project } from "."; @@ -14,6 +15,7 @@ import { intlMsg, loadDeployManifest, } from ".."; +import { Deployer } from "../deploy"; import { Web3ApiManifest, @@ -371,17 +373,27 @@ export class Web3ApiProject extends Project { return this._deployManifest; } - public async cacheDeploymentPackages(packages: { - deploy: string[]; - publish: string[]; - }): Promise { + public getDeploymentPackage(packageName: string): Deployer { + if (!this._deploymentPackagesCached) { + throw new Error("Deployment packages have not been cached"); + } + + const cachePath = this.getCachePath( + `${cacheLayout.deployEnvDir}/${packageName}` + ); + + // eslint-disable-next-line @typescript-eslint/no-require-imports + return require(cachePath).default as Deployer; + } + + public async cacheDeploymentPackages(packages: string[]): Promise { if (this._deploymentPackagesCached) { return; } this.removeCacheDir(cacheLayout.deployEnvDir); - for await (const deployPackage of packages.deploy) { + for await (const deployPackage of packages) { await this.copyIntoCache( `${cacheLayout.deployEnvDir}/${deployPackage}`, `${__dirname}/../deployers/${deployPackage}/*`, @@ -389,14 +401,6 @@ export class Web3ApiProject extends Project { ); } - for await (const publishPackage of packages.publish) { - await this.copyIntoCache( - `${cacheLayout.deployEnvDir}/${publishPackage}`, - `${__dirname}/../publishers/${publishPackage}/*`, - { up: true } - ); - } - this._deploymentPackagesCached = true; } diff --git a/packages/cli/src/lib/publishers/ens/index.ts b/packages/cli/src/lib/publishers/ens/index.ts deleted file mode 100644 index 0b1b8c24ad..0000000000 --- a/packages/cli/src/lib/publishers/ens/index.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* eslint-disable @typescript-eslint/no-require-imports */ -/* eslint-disable @typescript-eslint/no-var-requires */ -import { Publisher } from "../../deploy/DeploymentManager"; - -import ethers from "ethers"; -import { namehash } from "ethers/lib/utils"; - -const contentHash = require("content-hash"); -const ENS = require("@ensdomains/ensjs"); - -const ensConfig = { - resolverAddr: - process.env.ENS_RESOLVER_ADDR ?? - "0xf6305c19e814d2a75429Fd637d01F7ee0E77d615", - resolverAbi: [ - "function contenthash(bytes32 node) external view returns (bytes memory)", - "function setContenthash(bytes32 node, bytes calldata hash) external", - "event ContenthashChanged(bytes32 indexed node, bytes hash)", - ], -}; - -class ENSPublisher implements Publisher { - blockchain = "Ethereum"; - name = "ens"; - - constructor(public network: string) {} - - async publish( - cid: string, - config: { domainName: string; provider: string; privateKey: string } - ): Promise { - console.log(`Publishing ${cid} to ${config.domainName}...`); - - const connectionProvider = new ethers.providers.JsonRpcProvider( - config.provider as string - ); - const signer = new ethers.Wallet(config.privateKey as string).connect( - connectionProvider - ); - - const network = await connectionProvider.getNetwork(); - - const ens = new ENS.default({ - provider: signer.provider, - ensAddress: ENS.getEnsAddress(network.chainId), - }); - - const ensName = ens.name(config.domainName); - const resolver = await ensName.getResolver(); - - const contract = new ethers.Contract( - resolver, - ensConfig.resolverAbi, - signer - ); - - const hash: string = "0x" + contentHash.fromIpfs(cid); - - console.log(`Setting contenthash for ${config.domainName}`); - - const tx = await contract.setContenthash( - namehash(config.domainName as string), - hash - ); - - console.log("Waiting for transaction: " + tx.hash); - - await tx.wait(); - - console.log(`Publish to "${this.network}" successful!`); - - return `Published ${cid} to ${config.domainName}`; - } -} - -export default ENSPublisher; diff --git a/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts b/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts index 786ea49d8a..6df09cc222 100644 --- a/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts +++ b/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts @@ -8,7 +8,7 @@ export interface DeployManifest { format: "0.0.1-prealpha.1"; - deploy?: { + stages: { /** * This interface was referenced by `undefined`'s JSON-Schema definition * via the `patternProperty` "^.*$". @@ -22,28 +22,8 @@ export interface DeployManifest { */ [k: string]: unknown; }; - }; - }; - publish?: { - /** - * This interface was referenced by `undefined`'s JSON-Schema definition - * via the `patternProperty` "^.*$". - */ - [k: string]: { - package: string; - config?: { - /** - * This interface was referenced by `undefined`'s JSON-Schema definition - * via the `patternProperty` "^.*$". - */ - [k: string]: unknown; - }; - deployment?: - | string - | { - uri: string; - }; - publish?: string; + depends_on?: string; + uri?: string; }; }; __type: "DeployManifest"; diff --git a/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json b/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json index 20519dd606..a97defc98b 100644 --- a/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json +++ b/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json @@ -4,34 +4,14 @@ "additionalProperties": false, "required": [ "format", - "deployments" + "stages" ], "properties": { "format": { "type": "string", "const": "0.0.1-prealpha.1" }, - "deploy": { - "patternProperties": { - "^.*$": { - "type": "object", - "additionalProperties": false, - "properties": { - "package": { - "type": "string" - }, - "config": { - "patternProperties": { - "^.*$": { } - }, - "additionalProperties": false - } - }, - "required": ["package"] - } - } - }, - "publish": { + "stages": { "patternProperties": { "^.*$": { "type": "object", @@ -47,19 +27,12 @@ }, "additionalProperties": false }, - "deployment": { - "type": ["string", "object"], - "properties": { - "uri": { - "type" : "string", - "format": "web3apiUri" - } - }, - "additionalProperties": false, - "required": ["uri"] - }, - "publish": { + "depends_on": { "type": "string" + }, + "uri": { + "type": "string", + "format": "web3apiUri" } } } From 6e177a8086a8b5c868b968ceb517f8031aaf9e6b Mon Sep 17 00:00:00 2001 From: namesty Date: Thu, 14 Apr 2022 03:31:17 +0200 Subject: [PATCH 14/41] (chore): improved manifest formats and extensions --- packages/cli/lang/en.json | 3 + packages/cli/lang/es.json | 3 + packages/cli/package.json | 3 +- .../lib/deployers/ens/web3api.deploy.ext.json | 33 +- .../deployers/ipfs/web3api.deploy.ext.json | 14 +- .../web3api.deploy/0.0.1-prealpha.1.ts | 4 - .../web3api.deploy/0.0.1-prealpha.1.json | 5 +- yarn.lock | 569 +++++++++++++----- 8 files changed, 428 insertions(+), 206 deletions(-) diff --git a/packages/cli/lang/en.json b/packages/cli/lang/en.json index 2adcbc2783..e6595696d8 100644 --- a/packages/cli/lang/en.json +++ b/packages/cli/lang/en.json @@ -188,6 +188,9 @@ "lib_helpers_manifest_loadError": "Failed to load manifest from {path}", "lib_helpers_manifest_loadText": "Manifest loaded from {path}", "lib_helpers_manifest_loadWarning": "Warnings loading manifest from {path}", + "lib_helpers_deployManifestExt_loadError": "Failed to load deploy manifest extension from {path}", + "lib_helpers_deployManifestExt_loadText": "Load manifest extension from {path}", + "lib_helpers_deployManifestExt_loadWarning": "No manifest extension found in {path}", "lib_helpers_manifest_outputError": "Failed to output manifest to {path}", "lib_helpers_manifest_outputText": "Manifest written to {path}", "lib_helpers_manifest_outputWarning": "Warnings writing manifest to {path}", diff --git a/packages/cli/lang/es.json b/packages/cli/lang/es.json index db9e31f949..a1d1e8c568 100644 --- a/packages/cli/lang/es.json +++ b/packages/cli/lang/es.json @@ -189,6 +189,9 @@ "lib_helpers_manifest_loadError": "Failed to load manifest from {path}", "lib_helpers_manifest_loadText": "Manifest loaded from {path}", "lib_helpers_manifest_loadWarning": "Warnings loading manifest from {path}", + "lib_helpers_deployManifestExt_loadError": "Failed to load deploy manifest extension from {path}", + "lib_helpers_deployManifestExt_loadText": "Deploy manifest extension loaded from {path}", + "lib_helpers_deployManifestExt_loadWarning": "No deploy manifest extension found in {path}", "lib_helpers_manifest_outputError": "Failed to output manifest to {path}", "lib_helpers_manifest_outputText": "Manifest written to {path}", "lib_helpers_manifest_outputWarning": "Warnings writing manifest to {path}", diff --git a/packages/cli/package.json b/packages/cli/package.json index 91ff0665ee..5f451bdde4 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -16,8 +16,9 @@ "w3": "bin/w3" }, "scripts": { - "build": "rimraf ./build && tsc --project tsconfig.build.json && yarn build:envs", + "build": "rimraf ./build && tsc --project tsconfig.build.json && yarn build:envs && yarn build:deployers", "build:envs": "copyfiles ./src/lib/build-envs/**/**/* ./build/lib/build-envs/ -u 3", + "build:deployers": "copyfiles ./src/lib/deployers/**/web3api.deploy.ext.json ./build/lib/deployers -u 3", "prebuild": "ts-node ./scripts/generateIntlTypes.ts", "lint": "eslint --color -c ../../.eslintrc.js .", "test": "cross-env TEST=true jest --passWithNoTests --runInBand --verbose", diff --git a/packages/cli/src/lib/deployers/ens/web3api.deploy.ext.json b/packages/cli/src/lib/deployers/ens/web3api.deploy.ext.json index baf39908a0..180605c257 100644 --- a/packages/cli/src/lib/deployers/ens/web3api.deploy.ext.json +++ b/packages/cli/src/lib/deployers/ens/web3api.deploy.ext.json @@ -2,27 +2,22 @@ "id": "DeployManifest_ENS_WasmAsExt", "type": "object", "required": [ - "config" + "domainName", + "provider", + "ensRegistryAddress" ], "properties": { - "config": { - "type": "object", - "required": [ - "domainName", - "provider", - "privateKey" - ], - "properties": { - "domainName": { - "type": "string" - }, - "provider": { - "type": "string" - }, - "privateKey": { - "type": "string" - } - } + "domainName": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "privateKey": { + "type": "string" + }, + "ensRegistryAddress": { + "type": "string" } } } \ No newline at end of file diff --git a/packages/cli/src/lib/deployers/ipfs/web3api.deploy.ext.json b/packages/cli/src/lib/deployers/ipfs/web3api.deploy.ext.json index 4f72267f14..49a29bc911 100644 --- a/packages/cli/src/lib/deployers/ipfs/web3api.deploy.ext.json +++ b/packages/cli/src/lib/deployers/ipfs/web3api.deploy.ext.json @@ -2,19 +2,11 @@ "id": "DeployManifest_Deployer_WasmAsExt", "type": "object", "required": [ - "config" + "gatewayUri" ], "properties": { - "config": { - "type": "object", - "required": [ - "gatewayUri" - ], - "properties": { - "gatewayUri": { - "type": "string" - } - } + "gatewayUri": { + "type": "string" } } } \ No newline at end of file diff --git a/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts b/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts index 6df09cc222..c1c7dd7ccc 100644 --- a/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts +++ b/packages/js/core/src/manifest/formats/web3api.deploy/0.0.1-prealpha.1.ts @@ -16,10 +16,6 @@ export interface DeployManifest { [k: string]: { package: string; config?: { - /** - * This interface was referenced by `undefined`'s JSON-Schema definition - * via the `patternProperty` "^.*$". - */ [k: string]: unknown; }; depends_on?: string; diff --git a/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json b/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json index a97defc98b..d2ebf6e2e7 100644 --- a/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json +++ b/packages/manifest-schemas/formats/web3api.deploy/0.0.1-prealpha.1.json @@ -22,10 +22,7 @@ "type": "string" }, "config": { - "patternProperties": { - "^.*$": {} - }, - "additionalProperties": false + "type": "object" }, "depends_on": { "type": "string" diff --git a/yarn.lock b/yarn.lock index bcb4232666..971fb83edb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1410,7 +1410,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": version "7.17.8" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.8.tgz#3e56e4aff81befa55ac3ac6a0967349fd1c5bca2" integrity sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA== @@ -1487,6 +1487,11 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + "@cspotcode/source-map-consumer@0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" @@ -1551,6 +1556,19 @@ ts-node "^9" tslib "^2" +"@ensdomains/address-encoder@^0.1.7": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz#f948c485443d9ef7ed2c0c4790e931c33334d02d" + integrity sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg== + dependencies: + bech32 "^1.1.3" + blakejs "^1.1.0" + bn.js "^4.11.8" + bs58 "^4.0.1" + crypto-addr-codec "^0.1.7" + nano-base32 "^1.0.1" + ripemd160 "^2.0.2" + "@ensdomains/ens@0.4.4": version "0.4.4" resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.4.tgz#05e7bb138471a5e5844b4c1f263ec0ad7edcd272" @@ -1564,6 +1582,31 @@ testrpc "0.0.1" web3-utils "^1.0.0-beta.31" +"@ensdomains/ens@0.4.5": + version "0.4.5" + resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" + integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== + dependencies: + bluebird "^3.5.2" + eth-ens-namehash "^2.0.8" + solc "^0.4.20" + testrpc "0.0.1" + web3-utils "^1.0.0-beta.31" + +"@ensdomains/ensjs@^2.0.1": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ensdomains/ensjs/-/ensjs-2.1.0.tgz#0a7296c1f3d735ef019320d863a7846a0760c460" + integrity sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog== + dependencies: + "@babel/runtime" "^7.4.4" + "@ensdomains/address-encoder" "^0.1.7" + "@ensdomains/ens" "0.4.5" + "@ensdomains/resolver" "0.2.4" + content-hash "^2.5.2" + eth-ens-namehash "^2.0.8" + ethers "^5.0.13" + js-sha3 "^0.8.0" + "@ensdomains/resolver@0.2.4": version "0.2.4" resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" @@ -1600,7 +1643,7 @@ "@ethersproject/properties" ">=5.0.0-beta.131" "@ethersproject/strings" ">=5.0.0-beta.130" -"@ethersproject/abi@^5.0.0", "@ethersproject/abi@^5.6.0": +"@ethersproject/abi@5.6.0", "@ethersproject/abi@^5.0.0", "@ethersproject/abi@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.0.tgz#ea07cbc1eec2374d32485679c12408005895e9f3" integrity sha512-AhVByTwdXCc2YQ20v300w6KVHle9g2OFc28ZAFCPnJyEpkv1xKXjZcSTgWOlv1i+0dqlgF8RCF2Rn2KC1t+1Vg== @@ -1615,7 +1658,7 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/strings" "^5.6.0" -"@ethersproject/abstract-provider@^5.0.0", "@ethersproject/abstract-provider@^5.0.3", "@ethersproject/abstract-provider@^5.6.0": +"@ethersproject/abstract-provider@5.6.0", "@ethersproject/abstract-provider@^5.0.0", "@ethersproject/abstract-provider@^5.0.3", "@ethersproject/abstract-provider@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz#0c4ac7054650dbd9c476cf5907f588bbb6ef3061" integrity sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw== @@ -1628,7 +1671,7 @@ "@ethersproject/transactions" "^5.6.0" "@ethersproject/web" "^5.6.0" -"@ethersproject/abstract-signer@^5.0.0", "@ethersproject/abstract-signer@^5.0.3", "@ethersproject/abstract-signer@^5.6.0": +"@ethersproject/abstract-signer@5.6.0", "@ethersproject/abstract-signer@^5.0.0", "@ethersproject/abstract-signer@^5.0.3", "@ethersproject/abstract-signer@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz#9cd7ae9211c2b123a3b29bf47aab17d4d016e3e7" integrity sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ== @@ -1650,7 +1693,7 @@ "@ethersproject/logger" "^5.0.5" "@ethersproject/rlp" "^5.0.3" -"@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.0", "@ethersproject/address@^5.0.3", "@ethersproject/address@^5.6.0": +"@ethersproject/address@5.6.0", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.0", "@ethersproject/address@^5.0.3", "@ethersproject/address@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.6.0.tgz#13c49836d73e7885fc148ad633afad729da25012" integrity sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ== @@ -1661,14 +1704,14 @@ "@ethersproject/logger" "^5.6.0" "@ethersproject/rlp" "^5.6.0" -"@ethersproject/base64@^5.0.0", "@ethersproject/base64@^5.6.0": +"@ethersproject/base64@5.6.0", "@ethersproject/base64@^5.0.0", "@ethersproject/base64@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.6.0.tgz#a12c4da2a6fb86d88563216b0282308fc15907c9" integrity sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw== dependencies: "@ethersproject/bytes" "^5.6.0" -"@ethersproject/basex@^5.0.3", "@ethersproject/basex@^5.6.0": +"@ethersproject/basex@5.6.0", "@ethersproject/basex@^5.0.3", "@ethersproject/basex@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.6.0.tgz#9ea7209bf0a1c3ddc2a90f180c3a7f0d7d2e8a69" integrity sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ== @@ -1676,7 +1719,7 @@ "@ethersproject/bytes" "^5.6.0" "@ethersproject/properties" "^5.6.0" -"@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.0", "@ethersproject/bignumber@^5.0.10", "@ethersproject/bignumber@^5.0.6", "@ethersproject/bignumber@^5.6.0": +"@ethersproject/bignumber@5.6.0", "@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.0", "@ethersproject/bignumber@^5.0.10", "@ethersproject/bignumber@^5.0.6", "@ethersproject/bignumber@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.6.0.tgz#116c81b075c57fa765a8f3822648cf718a8a0e26" integrity sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA== @@ -1685,21 +1728,21 @@ "@ethersproject/logger" "^5.6.0" bn.js "^4.11.9" -"@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.6.0.tgz#81652f2a0e04533575befadce555213c11d8aa20" - integrity sha512-3hJPlYemb9V4VLfJF5BfN0+55vltPZSHU3QKUyP9M3Y2TcajbiRrz65UG+xVHOzBereB1b9mn7r12o177xgN7w== +"@ethersproject/bytes@5.6.1", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.6.0": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.6.1.tgz#24f916e411f82a8a60412344bf4a813b917eefe7" + integrity sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g== dependencies: "@ethersproject/logger" "^5.6.0" -"@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.0", "@ethersproject/constants@^5.0.3", "@ethersproject/constants@^5.6.0": +"@ethersproject/constants@5.6.0", "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.0", "@ethersproject/constants@^5.0.3", "@ethersproject/constants@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.6.0.tgz#55e3eb0918584d3acc0688e9958b0cedef297088" integrity sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA== dependencies: "@ethersproject/bignumber" "^5.6.0" -"@ethersproject/contracts@^5.0.0": +"@ethersproject/contracts@5.6.0", "@ethersproject/contracts@^5.0.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.6.0.tgz#60f2cfc7addd99a865c6c8cfbbcec76297386067" integrity sha512-74Ge7iqTDom0NX+mux8KbRUeJgu1eHZ3iv6utv++sLJG80FVuU9HnHeKVPfjd9s3woFhaFoQGf3B3iH/FrQmgw== @@ -1715,7 +1758,7 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/transactions" "^5.6.0" -"@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.0.0", "@ethersproject/hash@^5.0.3", "@ethersproject/hash@^5.6.0": +"@ethersproject/hash@5.6.0", "@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.0.0", "@ethersproject/hash@^5.0.3", "@ethersproject/hash@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.6.0.tgz#d24446a5263e02492f9808baa99b6e2b4c3429a2" integrity sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA== @@ -1729,7 +1772,7 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/strings" "^5.6.0" -"@ethersproject/hdnode@^5.0.0", "@ethersproject/hdnode@^5.6.0": +"@ethersproject/hdnode@5.6.0", "@ethersproject/hdnode@^5.0.0", "@ethersproject/hdnode@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.6.0.tgz#9dcbe8d629bbbcf144f2cae476337fe92d320998" integrity sha512-61g3Jp3nwDqJcL/p4nugSyLrpl/+ChXIOtCEM8UDmWeB3JCAt5FoLdOMXQc3WWkc0oM2C0aAn6GFqqMcS/mHTw== @@ -1747,7 +1790,7 @@ "@ethersproject/transactions" "^5.6.0" "@ethersproject/wordlists" "^5.6.0" -"@ethersproject/json-wallets@^5.0.0", "@ethersproject/json-wallets@^5.6.0": +"@ethersproject/json-wallets@5.6.0", "@ethersproject/json-wallets@^5.0.0", "@ethersproject/json-wallets@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.6.0.tgz#4c2fc27f17e36c583e7a252fb938bc46f98891e5" integrity sha512-fmh86jViB9r0ibWXTQipxpAGMiuxoqUf78oqJDlCAJXgnJF024hOOX7qVgqsjtbeoxmcLwpPsXNU0WEe/16qPQ== @@ -1766,7 +1809,7 @@ aes-js "3.0.0" scrypt-js "3.0.1" -"@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.0", "@ethersproject/keccak256@^5.0.3", "@ethersproject/keccak256@^5.6.0": +"@ethersproject/keccak256@5.6.0", "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.0", "@ethersproject/keccak256@^5.0.3", "@ethersproject/keccak256@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.6.0.tgz#fea4bb47dbf8f131c2e1774a1cecbfeb9d606459" integrity sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w== @@ -1774,19 +1817,19 @@ "@ethersproject/bytes" "^5.6.0" js-sha3 "0.8.0" -"@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.0", "@ethersproject/logger@^5.0.5", "@ethersproject/logger@^5.6.0": +"@ethersproject/logger@5.6.0", "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.0", "@ethersproject/logger@^5.0.5", "@ethersproject/logger@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.6.0.tgz#d7db1bfcc22fd2e4ab574cba0bb6ad779a9a3e7a" integrity sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg== -"@ethersproject/networks@^5.0.0", "@ethersproject/networks@^5.0.3", "@ethersproject/networks@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.0.tgz#486d03fff29b4b6b5414d47a232ded09fe10de5e" - integrity sha512-DaVzgyThzHgSDLuURhvkp4oviGoGe9iTZW4jMEORHDRCgSZ9K9THGFKqL+qGXqPAYLEgZTf5z2w56mRrPR1MjQ== +"@ethersproject/networks@5.6.1", "@ethersproject/networks@^5.0.0", "@ethersproject/networks@^5.0.3", "@ethersproject/networks@^5.6.0": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.1.tgz#7a21ed1f83e86121737b16841961ec99ccf5c9c7" + integrity sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg== dependencies: "@ethersproject/logger" "^5.6.0" -"@ethersproject/pbkdf2@^5.0.0", "@ethersproject/pbkdf2@^5.6.0": +"@ethersproject/pbkdf2@5.6.0", "@ethersproject/pbkdf2@^5.0.0", "@ethersproject/pbkdf2@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz#04fcc2d7c6bff88393f5b4237d906a192426685a" integrity sha512-Wu1AxTgJo3T3H6MIu/eejLFok9TYoSdgwRr5oGY1LTLfmGesDoSx05pemsbrPT2gG4cQME+baTSCp5sEo2erZQ== @@ -1794,7 +1837,7 @@ "@ethersproject/bytes" "^5.6.0" "@ethersproject/sha2" "^5.6.0" -"@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.0", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.6.0": +"@ethersproject/properties@5.6.0", "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.0", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.6.0.tgz#38904651713bc6bdd5bdd1b0a4287ecda920fa04" integrity sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg== @@ -1826,10 +1869,10 @@ bech32 "1.1.4" ws "7.2.3" -"@ethersproject/providers@^5.0.0": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.1.tgz#9a05f00ecbac59565bf6907c8d2af8ac33303b48" - integrity sha512-w8Wx15nH+aVDvnoKCyI1f3x0B5idmk/bDJXMEUqCfdO8Eadd0QpDx9lDMTMmenhOmf9vufLJXjpSm24D3ZnVpg== +"@ethersproject/providers@5.6.2", "@ethersproject/providers@^5.0.0": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.2.tgz#b9807b1c8c6f59fa2ee4b3cf6519724d07a9f422" + integrity sha512-6/EaFW/hNWz+224FXwl8+HdMRzVHt8DpPmu5MZaIQqx/K/ELnC9eY236SMV7mleCM3NnEArFwcAAxH5kUUgaRg== dependencies: "@ethersproject/abstract-provider" "^5.6.0" "@ethersproject/abstract-signer" "^5.6.0" @@ -1851,7 +1894,7 @@ bech32 "1.1.4" ws "7.4.6" -"@ethersproject/random@^5.0.0", "@ethersproject/random@^5.0.3", "@ethersproject/random@^5.6.0": +"@ethersproject/random@5.6.0", "@ethersproject/random@^5.0.0", "@ethersproject/random@^5.0.3", "@ethersproject/random@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.6.0.tgz#1505d1ab6a250e0ee92f436850fa3314b2cb5ae6" integrity sha512-si0PLcLjq+NG/XHSZz90asNf+YfKEqJGVdxoEkSukzbnBgC8rydbgbUgBbBGLeHN4kAJwUFEKsu3sCXT93YMsw== @@ -1859,7 +1902,7 @@ "@ethersproject/bytes" "^5.6.0" "@ethersproject/logger" "^5.6.0" -"@ethersproject/rlp@^5.0.0", "@ethersproject/rlp@^5.0.3", "@ethersproject/rlp@^5.6.0": +"@ethersproject/rlp@5.6.0", "@ethersproject/rlp@^5.0.0", "@ethersproject/rlp@^5.0.3", "@ethersproject/rlp@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.6.0.tgz#55a7be01c6f5e64d6e6e7edb6061aa120962a717" integrity sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g== @@ -1867,7 +1910,7 @@ "@ethersproject/bytes" "^5.6.0" "@ethersproject/logger" "^5.6.0" -"@ethersproject/sha2@^5.0.0", "@ethersproject/sha2@^5.0.3", "@ethersproject/sha2@^5.6.0": +"@ethersproject/sha2@5.6.0", "@ethersproject/sha2@^5.0.0", "@ethersproject/sha2@^5.0.3", "@ethersproject/sha2@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.6.0.tgz#364c4c11cc753bda36f31f001628706ebadb64d9" integrity sha512-1tNWCPFLu1n3JM9t4/kytz35DkuF9MxqkGGEHNauEbaARdm2fafnOyw1s0tIQDPKF/7bkP1u3dbrmjpn5CelyA== @@ -1876,7 +1919,7 @@ "@ethersproject/logger" "^5.6.0" hash.js "1.1.7" -"@ethersproject/signing-key@^5.0.0", "@ethersproject/signing-key@^5.6.0": +"@ethersproject/signing-key@5.6.0", "@ethersproject/signing-key@^5.0.0", "@ethersproject/signing-key@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.6.0.tgz#4f02e3fb09e22b71e2e1d6dc4bcb5dafa69ce042" integrity sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA== @@ -1888,7 +1931,7 @@ elliptic "6.5.4" hash.js "1.1.7" -"@ethersproject/solidity@^5.0.0": +"@ethersproject/solidity@5.6.0", "@ethersproject/solidity@^5.0.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.6.0.tgz#64657362a596bf7f5630bdc921c07dd78df06dc3" integrity sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww== @@ -1900,7 +1943,7 @@ "@ethersproject/sha2" "^5.6.0" "@ethersproject/strings" "^5.6.0" -"@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.0", "@ethersproject/strings@^5.0.3", "@ethersproject/strings@^5.6.0": +"@ethersproject/strings@5.6.0", "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.0", "@ethersproject/strings@^5.0.3", "@ethersproject/strings@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.6.0.tgz#9891b26709153d996bf1303d39a7f4bc047878fd" integrity sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg== @@ -1909,7 +1952,7 @@ "@ethersproject/constants" "^5.6.0" "@ethersproject/logger" "^5.6.0" -"@ethersproject/transactions@^5.0.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.0.3", "@ethersproject/transactions@^5.6.0": +"@ethersproject/transactions@5.6.0", "@ethersproject/transactions@^5.0.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.0.3", "@ethersproject/transactions@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.6.0.tgz#4b594d73a868ef6e1529a2f8f94a785e6791ae4e" integrity sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg== @@ -1924,7 +1967,7 @@ "@ethersproject/rlp" "^5.6.0" "@ethersproject/signing-key" "^5.6.0" -"@ethersproject/units@^5.0.0": +"@ethersproject/units@5.6.0", "@ethersproject/units@^5.0.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.6.0.tgz#e5cbb1906988f5740254a21b9ded6bd51e826d9c" integrity sha512-tig9x0Qmh8qbo1w8/6tmtyrm/QQRviBh389EQ+d8fP4wDsBrJBf08oZfoiz1/uenKK9M78yAP4PoR7SsVoTjsw== @@ -1933,7 +1976,7 @@ "@ethersproject/constants" "^5.6.0" "@ethersproject/logger" "^5.6.0" -"@ethersproject/wallet@^5.0.0": +"@ethersproject/wallet@5.6.0", "@ethersproject/wallet@^5.0.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.6.0.tgz#33d11a806d783864208f348709a5a3badac8e22a" integrity sha512-qMlSdOSTyp0MBeE+r7SUhr1jjDlC1zAXB8VD84hCnpijPQiSNbxr6GdiLXxpUs8UKzkDiNYYC5DRI3MZr+n+tg== @@ -1954,7 +1997,7 @@ "@ethersproject/transactions" "^5.6.0" "@ethersproject/wordlists" "^5.6.0" -"@ethersproject/web@^5.0.0", "@ethersproject/web@^5.0.4", "@ethersproject/web@^5.6.0": +"@ethersproject/web@5.6.0", "@ethersproject/web@^5.0.0", "@ethersproject/web@^5.0.4", "@ethersproject/web@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.6.0.tgz#4bf8b3cbc17055027e1a5dd3c357e37474eaaeb8" integrity sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg== @@ -1965,7 +2008,7 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/strings" "^5.6.0" -"@ethersproject/wordlists@^5.0.0", "@ethersproject/wordlists@^5.6.0": +"@ethersproject/wordlists@5.6.0", "@ethersproject/wordlists@^5.0.0", "@ethersproject/wordlists@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.6.0.tgz#79e62c5276e091d8575f6930ba01a29218ded032" integrity sha512-q0bxNBfIX3fUuAo9OmjlEYxP40IB8ABgb7HjEZCL5IKubzV3j30CWi2rqQbjTS2HfoyQbfINoKcTVWP4ejwR7Q== @@ -2112,11 +2155,11 @@ tslib "~2.1.0" "@graphql-tools/import@^6.2.6": - version "6.6.8" - resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.6.8.tgz#b8fdeda1652b2fae4776fcc89ad7b7a3e33de4c4" - integrity sha512-+CyBgZYof3JyP9oe5UKxIGpADmE4Y/vn9q0GmD/XuX2uyve7kMj2NOkkXE66KSC8NrA7Y60uvoO+ZpW1GlVu2Q== + version "6.6.9" + resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.6.9.tgz#53e1517074c756b5191d23d4f1528246913d44ba" + integrity sha512-sKaLqvPmNLQlY4te+nnBhRrf5WBISoiyVkbriCLz0kHw805iHdJaU2KxUoHsRTR7WlYq0g9gzB0oVaRh99Q5aA== dependencies: - "@graphql-tools/utils" "8.6.4" + "@graphql-tools/utils" "8.6.5" resolve-from "5.0.0" tslib "~2.3.0" @@ -2152,12 +2195,12 @@ "@graphql-tools/utils" "^7.7.0" tslib "~2.2.0" -"@graphql-tools/merge@8.2.5": - version "8.2.5" - resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.5.tgz#50e273ef78e485ff6dd012a85dfcf72dd8a948ea" - integrity sha512-0GUl47Ns1SFU+Y+4mt0IQt0HXeF3dkGrmu7plsQ3153aKNCfAmSZ0J/9seM0aPDsCYlC2zwwT70OM2YEyobh+w== +"@graphql-tools/merge@8.2.6": + version "8.2.6" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.6.tgz#7fb615fa9c143c3151ff025e501d52bd48186d19" + integrity sha512-dkwTm4czMISi/Io47IVvq2Fl9q4TIGKpJ0VZjuXYdEFkECyH6A5uwxZfPVandZG+gQs8ocFFoa6RisiUJLZrJw== dependencies: - "@graphql-tools/utils" "8.6.4" + "@graphql-tools/utils" "8.6.5" tslib "~2.3.0" "@graphql-tools/merge@^6.2.12": @@ -2179,12 +2222,12 @@ value-or-promise "1.0.6" "@graphql-tools/schema@^8.0.2": - version "8.3.4" - resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.4.tgz#39a6cf42476401e3676f2cd9140458c13436ccff" - integrity sha512-CTvJQoeb7aw9oY0heMW3kU8/zeeSR6gffhJEBjTRyKnmXi/fB8bJkQ4W5+MuEUy+iG4lPMczXCcB9J5gj8AF+g== + version "8.3.6" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.6.tgz#80cfe3eba53eb6390a60a30078d7efbdaa5cc0b7" + integrity sha512-7tWYRQ8hB/rv2zAtv2LtnQl4UybyJPtRz/VLKRmgi7+F5t8iYBahmmsxMDAYMWMmWMqEDiKk54TvAes+J069rQ== dependencies: - "@graphql-tools/merge" "8.2.5" - "@graphql-tools/utils" "8.6.4" + "@graphql-tools/merge" "8.2.6" + "@graphql-tools/utils" "8.6.5" tslib "~2.3.0" value-or-promise "1.0.11" @@ -2220,10 +2263,10 @@ dependencies: tslib "~2.3.0" -"@graphql-tools/utils@8.6.4": - version "8.6.4" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.6.4.tgz#982e7b94c2267e2b182e84edcec0695dc021e6cb" - integrity sha512-RttGqPfScCeiNgbgGyAQvTvbNZU3kjAST3s0T4tV+tPlXinHqFVuFRV8ZHu5Zs9yu5wuyEyEkvB86bvKb6GiNA== +"@graphql-tools/utils@8.6.5": + version "8.6.5" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.6.5.tgz#ac04571b03f854c7a938b2ab700516a6c6d32335" + integrity sha512-mjOtaWiS2WIqRz/cq5gaeM3sVrllcu2xbtHROw1su1v3xWa3D3dKgn8Lrl7+tvWs5WUVySsBss/VZ3WdoPkCrA== dependencies: tslib "~2.3.0" @@ -4037,9 +4080,9 @@ integrity sha512-M5qhhfuTt4fwHGqqANNQilp3Htb5cHwBxlMHDUw/TYRVkEp3s3IIFSH3Fe9HIAeEtnO4p3SSowLmCVavdRYfpw== "@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6": - version "7.0.10" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.10.tgz#9b05b7896166cd00e9cbd59864853abf65d9ac23" - integrity sha512-BLO9bBq59vW3fxCpD4o0N4U+DXsvwvIcl+jofw0frQo/GrBFC+/jRZj1E7kgp6dvTyNmA4y6JCV5Id/r3mNP5A== + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== "@types/json5@^0.0.29": version "0.0.29" @@ -4047,9 +4090,9 @@ integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/lodash@^4.14.168": - version "4.14.180" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.180.tgz#4ab7c9ddfc92ec4a887886483bc14c79fb380670" - integrity sha512-XOKXa1KIxtNXgASAnwj7cnttJxS4fksBRywK/9LzRV5YxrF80BXZIGeQSuoESQ/VkUj30Ae0+YcuHc15wJCB2g== + version "4.14.181" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.181.tgz#d1d3740c379fda17ab175165ba04e2d03389385d" + integrity sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag== "@types/minimatch@*", "@types/minimatch@^3.0.3": version "3.0.5" @@ -4067,9 +4110,9 @@ integrity sha512-wH6Tu9mbiOt0n5EvdoWy0VGQaJMHfLIxY/6wS0xLC7CV1taM6gESEzcYy0ZlWvxxiiljYvfDIvz4hHbUUDRlhw== "@types/node@*": - version "17.0.22" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.22.tgz#38b6c4b9b2f3ed9f2e376cce42a298fb2375251e" - integrity sha512-8FwbVoG4fy+ykY86XCAclKZDORttqE5/s7dyWZKLXTdv3vRy5HozBEinG5IqhvPXXzIZEcTVbuHlQEI6iuwcmw== + version "17.0.23" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da" + integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw== "@types/node@12.0.0": version "12.0.0" @@ -4147,9 +4190,9 @@ "@types/react" "*" "@types/react@*", "@types/react@>=16.9.0": - version "17.0.41" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.41.tgz#6e179590d276394de1e357b3f89d05d7d3da8b85" - integrity sha512-chYZ9ogWUodyC7VUTRBfblysKLjnohhFY9bGLwvnUFFy48+vB9DikmB3lW0qTFmBcKSzmdglcvkHK71IioOlDA== + version "17.0.43" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.43.tgz#4adc142887dd4a2601ce730bc56c3436fdb07a55" + integrity sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -4720,9 +4763,9 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4: uri-js "^4.2.2" ajv@^8.0.1: - version "8.10.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" - integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== + version "8.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -4781,9 +4824,9 @@ ansi-regex@^2.0.0: integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= 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= + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" + integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== ansi-regex@^4.0.0, ansi-regex@^4.1.0: version "4.1.1" @@ -5162,6 +5205,16 @@ async@^2.1.2, async@^2.6.2: dependencies: lodash "^4.17.14" +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" @@ -5951,7 +6004,7 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bech32@1.1.4: +bech32@1.1.4, bech32@^1.1.3: version "1.1.4" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== @@ -5961,6 +6014,11 @@ before-after-hook@^2.2.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ== +big-integer@1.6.36: + version "1.6.36" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" + integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -6034,7 +6092,7 @@ bn.js@4.11.6: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.9: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== @@ -6060,7 +6118,7 @@ body-parser@1.19.0: raw-body "2.4.0" type-is "~1.6.17" -body-parser@1.19.2, body-parser@^1.16.0: +body-parser@1.19.2: version "1.19.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== @@ -6076,6 +6134,24 @@ body-parser@1.19.2, body-parser@^1.16.0: raw-body "2.4.3" type-is "~1.6.18" +body-parser@^1.16.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + bonjour@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" @@ -6137,7 +6213,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1, braces@~3.0.2: +braces@^3.0.2, 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== @@ -6268,7 +6344,7 @@ bs-logger@0.x: dependencies: fast-json-stable-stringify "2.x" -bs58@^4.0.0: +bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= @@ -6321,6 +6397,14 @@ buffer-xor@^1.0.3: resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= +buffer@6.0.3, buffer@^6.0.1: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + buffer@^4.3.0: version "4.9.2" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" @@ -6338,14 +6422,6 @@ buffer@^5.0.5, buffer@^5.2.1, buffer@^5.4.3, buffer@^5.5.0, buffer@^5.6.0, buffe base64-js "^1.3.1" ieee754 "^1.1.13" -buffer@^6.0.1: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - bufferutil@^4.0.1: version "4.0.6" resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.6.tgz#ebd6c67c7922a0e902f053e5d8be5ec850e48433" @@ -6590,9 +6666,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001035, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001317: - version "1.0.30001319" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001319.tgz#eb4da4eb3ecdd409f7ba1907820061d56096e88f" - integrity sha512-xjlIAFHucBRSMUo1kb5D4LYgcN1M45qdKP++lhqowDpwJwGkpIRTt5qQqnhxjj1vHcI7nrJxWhCC1ATrCEBTcw== + version "1.0.30001325" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001325.tgz#2b4ad19b77aa36f61f2eaf72e636d7481d55e606" + integrity sha512-sB1bZHjseSjDtijV1Hb7PB2Zd58Kyx+n/9EotvZ4Qcz2K3d0lWB8dB4nb8wN/TsOGFq3UuAm0zQZNQ4SoR7TrQ== capture-exit@^2.0.0: version "2.0.0" @@ -6815,12 +6891,12 @@ clean-stack@^2.0.0: integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== cli-color@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-2.0.1.tgz#93e3491308691f1e46beb78b63d0fb2585e42ba6" - integrity sha512-eBbxZF6fqPUNnf7CLAFOersUnyYzv83tHFLSlts+OAHsNendaqv2tHCq+/MO+b3Y+9JeoUlIvobyxG/Z8GNeOg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-2.0.2.tgz#e295addbae470800def0254183c648531cdf4e3f" + integrity sha512-g4JYjrTW9MGtCziFNjkqp3IMpGhnJyeB0lOtRPjQkYhXzKYr6tYnXKyEVnMzITxhpbahsEW9KsxOYIDKwcsIBw== dependencies: d "^1.0.1" - es5-ext "^0.10.53" + es5-ext "^0.10.59" es6-iterator "^2.0.3" memoizee "^0.4.15" timers-ext "^0.1.7" @@ -7032,6 +7108,11 @@ color@^3.0.0: color-convert "^1.9.3" color-string "^1.6.0" +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, colors@^1.3.3: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" @@ -7550,6 +7631,19 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +crypto-addr-codec@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/crypto-addr-codec/-/crypto-addr-codec-0.1.7.tgz#e16cea892730178fe25a38f6d15b680cab3124ae" + integrity sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg== + dependencies: + base-x "^3.0.8" + big-integer "1.6.36" + blakejs "^1.1.0" + bs58 "^4.0.1" + ripemd160-min "0.0.6" + safe-buffer "^5.2.0" + sha3 "^2.1.1" + crypto-browserify@3.12.0, crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -7636,13 +7730,13 @@ css-select@^2.0.0: nth-check "^1.0.2" css-select@^4.1.3: - version "4.2.1" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd" - integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== dependencies: boolbase "^1.0.0" - css-what "^5.1.0" - domhandler "^4.3.0" + css-what "^6.0.1" + domhandler "^4.3.1" domutils "^2.8.0" nth-check "^2.0.1" @@ -7667,10 +7761,10 @@ css-what@^3.2.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== -css-what@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" - integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== css@^2.0.0: version "2.2.4" @@ -7811,6 +7905,11 @@ csv-stringify@^5.6.2: resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-5.6.5.tgz#c6d74badda4b49a79bf4e72f91cce1e33b94de00" integrity sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A== +cycle@1.0.x: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" + integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI= + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -8029,6 +8128,11 @@ delimit-stream@0.1.0: resolved "https://registry.yarnpkg.com/delimit-stream/-/delimit-stream-0.1.0.tgz#9b8319477c0e5f8aeb3ce357ae305fc25ea1cd2b" integrity sha1-m4MZR3wOX4rrPONXrjBfwl6hzSs= +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== + depd@^1.1.2, depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -8047,6 +8151,11 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -8269,7 +8378,7 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" -domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0: +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== @@ -8376,9 +8485,9 @@ electron-fetch@^1.7.2: encoding "^0.1.13" electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.47, electron-to-chromium@^1.4.84: - version "1.4.89" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.89.tgz#33c06592812a17a7131873f4596579084ce33ff8" - integrity sha512-z1Axg0Fu54fse8wN4fd+GAINdU5mJmLtcl6bqIcYyzNVGONcfHAeeJi88KYMQVKalhXlYuVPzKkFIU5VD0raUw== + version "1.4.103" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz#abfe376a4d70fa1e1b4b353b95df5d6dfd05da3a" + integrity sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg== elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" @@ -8530,9 +8639,9 @@ error@^7.0.0: string-template "~0.2.1" es-abstract@^1.17.2, es-abstract@^1.18.5, es-abstract@^1.19.0, es-abstract@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" - integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== + version "1.19.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.2.tgz#8f7b696d8f15b167ae3640b4060670f3d054143f" + integrity sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" @@ -8540,15 +8649,15 @@ es-abstract@^1.17.2, es-abstract@^1.18.5, es-abstract@^1.19.0, es-abstract@^1.19 get-intrinsic "^1.1.1" get-symbol-description "^1.0.0" has "^1.0.3" - has-symbols "^1.0.2" + has-symbols "^1.0.3" internal-slot "^1.0.3" is-callable "^1.2.4" - is-negative-zero "^2.0.1" + is-negative-zero "^2.0.2" is-regex "^1.1.4" is-shared-array-buffer "^1.0.1" is-string "^1.0.7" - is-weakref "^1.0.1" - object-inspect "^1.11.0" + is-weakref "^1.0.2" + object-inspect "^1.12.0" object-keys "^1.1.1" object.assign "^4.1.2" string.prototype.trimend "^1.0.4" @@ -8564,7 +8673,7 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.59, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: version "0.10.59" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.59.tgz#71038939730eb6f4f165f1421308fb60be363bc6" integrity sha512-cOgyhW0tIJyQY1Kfw6Kr0viu9ZlUctVchRMZ7R0HiH3dxTSp5zJDLecwxUqPUrGKMsgBI1wd1FL+d9Jxfi4cLw== @@ -9153,6 +9262,42 @@ ethers@5.0.7: "@ethersproject/web" "^5.0.0" "@ethersproject/wordlists" "^5.0.0" +ethers@5.6.2, ethers@^5.0.13: + version "5.6.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.6.2.tgz#e75bac7f038c5e0fdde667dba62fc223924143a2" + integrity sha512-EzGCbns24/Yluu7+ToWnMca3SXJ1Jk1BvWB7CCmVNxyOeM4LLvw2OLuIHhlkhQk1dtOcj9UMsdkxUh8RiG1dxQ== + dependencies: + "@ethersproject/abi" "5.6.0" + "@ethersproject/abstract-provider" "5.6.0" + "@ethersproject/abstract-signer" "5.6.0" + "@ethersproject/address" "5.6.0" + "@ethersproject/base64" "5.6.0" + "@ethersproject/basex" "5.6.0" + "@ethersproject/bignumber" "5.6.0" + "@ethersproject/bytes" "5.6.1" + "@ethersproject/constants" "5.6.0" + "@ethersproject/contracts" "5.6.0" + "@ethersproject/hash" "5.6.0" + "@ethersproject/hdnode" "5.6.0" + "@ethersproject/json-wallets" "5.6.0" + "@ethersproject/keccak256" "5.6.0" + "@ethersproject/logger" "5.6.0" + "@ethersproject/networks" "5.6.1" + "@ethersproject/pbkdf2" "5.6.0" + "@ethersproject/properties" "5.6.0" + "@ethersproject/providers" "5.6.2" + "@ethersproject/random" "5.6.0" + "@ethersproject/rlp" "5.6.0" + "@ethersproject/sha2" "5.6.0" + "@ethersproject/signing-key" "5.6.0" + "@ethersproject/solidity" "5.6.0" + "@ethersproject/strings" "5.6.0" + "@ethersproject/transactions" "5.6.0" + "@ethersproject/units" "5.6.0" + "@ethersproject/wallet" "5.6.0" + "@ethersproject/web" "5.6.0" + "@ethersproject/wordlists" "5.6.0" + ethjs-unit@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" @@ -9478,6 +9623,11 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== +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" @@ -9793,7 +9943,7 @@ fork-ts-checker-webpack-plugin@3.1.1: tapable "^1.0.0" worker-rpc "^0.1.0" -form-data@4.0.0: +form-data@4.0.0, form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== @@ -10731,6 +10881,17 @@ http-errors@1.8.1: statuses ">= 1.5.0 < 2" toidentifier "1.0.1" +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + http-errors@~1.6.2: version "1.6.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" @@ -11554,15 +11715,15 @@ is-negated-glob@^1.0.0: resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= -is-negative-zero@^2.0.1: +is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== is-number-object@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" - integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== dependencies: has-tostringtag "^1.0.0" @@ -11685,9 +11846,11 @@ is-root@2.1.0: integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== is-shared-array-buffer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" - integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" is-ssh@^1.3.0: version "1.3.3" @@ -11755,7 +11918,7 @@ is-utf8@^0.2.0: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= -is-weakref@^1.0.1: +is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== @@ -11826,7 +11989,7 @@ isomorphic-ws@4.0.1: resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== -isstream@~0.1.2: +isstream@0.1.x, isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= @@ -13955,12 +14118,12 @@ micromatch@^3.1.10, micromatch@^3.1.4: to-regex "^3.0.2" micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" - integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: - braces "^3.0.1" - picomatch "^2.2.3" + braces "^3.0.2" + picomatch "^2.3.1" miller-rabin@^4.0.0: version "4.0.1" @@ -14069,7 +14232,7 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@^1.1.0, minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: +minimist@^1.1.0, minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -14205,11 +14368,11 @@ mkdirp@*, mkdirp@1.x, mkdirp@^1.0.3, mkdirp@^1.0.4: integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: - minimist "^1.2.5" + minimist "^1.2.6" mock-fs@^4.1.0: version "4.14.0" @@ -14467,15 +14630,20 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== +nano-base32@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/nano-base32/-/nano-base32-1.0.1.tgz#ba548c879efcfb90da1c4d9e097db4a46c9255ef" + integrity sha1-ulSMh578+5DaHE2eCX20pGySVe8= + nano-json-stream-parser@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= nanoid@^3.1.12, nanoid@^3.1.3: - version "3.3.1" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" - integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== + version "3.3.2" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.2.tgz#c89622fafb4381cd221421c69ec58547a1eec557" + integrity sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA== nanomatch@^1.2.9: version "1.2.13" @@ -14599,9 +14767,9 @@ node-forge@^0.10.0: integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" - integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + version "4.4.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4" + integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ== node-gyp@^5.0.2: version "5.1.1" @@ -14961,7 +15129,7 @@ object-hash@^2.0.1: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== -object-inspect@^1.11.0, object-inspect@^1.9.0: +object-inspect@^1.12.0, object-inspect@^1.9.0: version "1.12.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== @@ -15056,6 +15224,13 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -15680,7 +15855,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -16377,9 +16552,9 @@ postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: uniq "^1.0.1" postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: - version "6.0.9" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" - integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== + version "6.0.10" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -16471,9 +16646,9 @@ prettier@2.2.1: integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== prettier@^2.2.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.0.tgz#12f8f504c4d8ddb76475f441337542fa799207d4" - integrity sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A== + version "2.6.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" + integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== pretty-bytes@^5.1.0: version "5.6.0" @@ -16568,6 +16743,17 @@ promise@^8.0.3: dependencies: asap "~2.0.6" +prompt@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.2.2.tgz#b624fcf53aa6c8c5637e009c193ef69eee45dbe0" + integrity sha512-XNXhNv3PUHJDcDkISpCwSJxtw9Bor4FZnlMUDW64N/KCPdxhfVlpD5+YUXI/Z8a9QWmOhs9KSiVtR8nzPS0BYA== + dependencies: + "@colors/colors" "1.5.0" + async "~0.9.0" + read "1.0.x" + revalidator "0.1.x" + winston "2.x" + prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -16719,6 +16905,13 @@ q@^1.1.2, q@^1.5.1: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= +qs@6.10.3, qs@^6.9.4: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" + qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" @@ -16729,13 +16922,6 @@ qs@6.9.7: resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== -qs@^6.9.4: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== - dependencies: - side-channel "^1.0.4" - qs@~6.5.2: version "6.5.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" @@ -16870,6 +17056,16 @@ raw-body@2.4.3: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + react-app-polyfill@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-1.0.6.tgz#890f8d7f2842ce6073f030b117de9130a5f385f0" @@ -17158,7 +17354,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -read@1, read@~1.0.1: +read@1, read@1.0.x, read@~1.0.1: version "1.0.7" resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= @@ -17617,6 +17813,11 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +revalidator@0.1.x: + version "0.1.8" + resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" + integrity sha1-/s5hv6DBtSoga9axgZgYS91SOjs= + rework-visit@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a" @@ -17668,7 +17869,12 @@ rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3, rimraf@^2.7.1: dependencies: glob "^7.1.3" -ripemd160@^2.0.0, ripemd160@^2.0.1: +ripemd160-min@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/ripemd160-min/-/ripemd160-min-0.0.6.tgz#a904b77658114474d02503e819dcc55853b67e62" + integrity sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A== + +ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== @@ -18004,6 +18210,13 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +sha3@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/sha3/-/sha3-2.1.4.tgz#000fac0fe7c2feac1f48a25e7a31b52a6492cc8f" + integrity sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg== + dependencies: + buffer "6.0.3" + shallow-clone@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060" @@ -18447,6 +18660,11 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +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@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.5.tgz#a19b0b01947e0029c8e451d5d61a498f5bb1471b" @@ -18469,6 +18687,11 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + "statuses@>= 1.4.0 < 2", "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" @@ -19374,13 +19597,13 @@ ts-pnp@^1.1.6: integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== tsconfig-paths@^3.9.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.0.tgz#4fcc48f9ccea8826c41b9ca093479de7f5018976" - integrity sha512-cg/1jAZoL57R39+wiw4u/SCC6Ic9Q5NqjBOb+9xISedOYurfog9ZNmKJSxAnb2m/5Bq4lE9lhUcau33Ml8DM0g== + version "3.14.1" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" + integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== dependencies: "@types/json5" "^0.0.29" json5 "^1.0.1" - minimist "^1.2.0" + minimist "^1.2.6" strip-bom "^3.0.0" tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: @@ -19517,9 +19740,9 @@ typescript@4.0.7: integrity sha512-yi7M4y74SWvYbnazbn8/bmJmX4Zlej39ZOqwG/8dut/MYoSQ119GY9ZFbbGsD4PFZYWxqik/XsP3vk3+W5H3og== typescript@^4.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.2.tgz#fe12d2727b708f4eef40f51598b3398baa9611d4" - integrity sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg== + version "4.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" + integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== uglify-js@^2.8.29: version "2.8.29" @@ -20634,6 +20857,18 @@ window-size@^0.2.0: resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= +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, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" From 37d109aa86924c8f3997a3b04e9d8fae841a95a0 Mon Sep 17 00:00:00 2001 From: namesty Date: Thu, 14 Apr 2022 03:32:28 +0200 Subject: [PATCH 15/41] (feat): added manifest ext validation and logging --- packages/cli/src/commands/deploy.ts | 85 ++++++++---- packages/cli/src/lib/deploy/asciiTree.ts | 128 ++++++++++++++++++ packages/cli/src/lib/deploy/deployer.ts | 34 ++++- packages/cli/src/lib/deploy/index.ts | 9 ++ .../cli/src/lib/deployers/ipfs/formData.ts | 2 - packages/cli/src/lib/deployers/ipfs/index.ts | 4 +- packages/cli/src/lib/helpers/spinner.ts | 27 ++++ packages/cli/src/lib/manifest/web3api/load.ts | 42 +++++- .../cli/src/lib/project/Web3ApiProject.ts | 17 ++- 9 files changed, 311 insertions(+), 37 deletions(-) create mode 100644 packages/cli/src/lib/deploy/asciiTree.ts diff --git a/packages/cli/src/commands/deploy.ts b/packages/cli/src/commands/deploy.ts index 5de79b3d62..d71f3aea7b 100644 --- a/packages/cli/src/commands/deploy.ts +++ b/packages/cli/src/commands/deploy.ts @@ -4,6 +4,7 @@ import { Web3ApiProject, defaultWeb3ApiManifest, resolvePathIfExists, + DeployPackage, } from "../lib"; import { DeployerHandler } from "../lib/deploy/deployer"; @@ -11,7 +12,8 @@ import chalk from "chalk"; import fs from "fs"; import nodePath from "path"; import { GluegunToolbox, GluegunPrint } from "gluegun"; -import { Uri } from "@web3api/core-js"; +import { Uri, DeployManifest } from "@web3api/core-js"; +import { validate } from "jsonschema"; const defaultManifestStr = defaultWeb3ApiManifest.join(" | "); const optionsStr = intlMsg.commands_deploy_options_options(); @@ -22,11 +24,10 @@ ${chalk.bold("w3 deploy")} [${optionsStr}] ${optionsStr[0].toUpperCase() + optionsStr.slice(1)}: -h, --help ${intlMsg.commands_deploy_options_h()} - -m, --manifest-file <${pathStr}> ${intlMsg.commands_deploy_options_m({ + -m, --manifest-file <${pathStr}> ${intlMsg.commands_deploy_options_m({ default: defaultManifestStr, })} - -v, --verbose ${intlMsg.commands_deploy_options_v()} -`; + -v, --verbose ${intlMsg.commands_deploy_options_v()}`; export default { alias: ["b"], @@ -88,21 +89,41 @@ export default { throw new Error("No deploy manifest"); } - const packages = Object.values(deployManifest.stages).map((d) => d.package); + const packageNames = [ + ...new Set(Object.values(deployManifest.stages).map((d) => d.package)), + ]; - sanitizePackages(packages); + sanitizePackages(packageNames); - await project.cacheDeploymentPackages(packages); + await project.cacheDeploymentPackages(packageNames); + + const packageMap: Record = {}; + const stageToPackageMap: Record = {}; + + for await (const packageName of packageNames) { + packageMap[packageName] = await project.getDeploymentPackage(packageName); + } + + Object.entries(deployManifest.stages).forEach(([stageName, stageValue]) => { + stageToPackageMap[stageName] = packageMap[stageValue.package]; + }); + + validateManifestWithExts(deployManifest, stageToPackageMap); const handlers: Record = {}; const roots: { handler: DeployerHandler; uri: Uri }[] = []; // Create all handlers - Object.entries(deployManifest.stages).forEach(([key, value]) => { - const publisher = project.getDeploymentPackage(value.package); - const handler = new DeployerHandler(key, publisher, value.config); + Object.entries(deployManifest.stages).forEach(([stageName, stageValue]) => { + const publisher = stageToPackageMap[stageName].deployer; + const handler = new DeployerHandler( + stageName, + publisher, + stageValue.config, + print + ); - handlers[key] = handler; + handlers[stageName] = handler; }); // Establish dependency chains @@ -124,22 +145,13 @@ export default { // Execute roots - roots.forEach((root) => { - console.log(root.handler.getList()); - }); - - const uris: Uri[][] = []; - for await (const root of roots) { - uris.push(await root.handler.handle(root.uri)); + print.info(`\nExecuting deployment chain: \n`); + root.handler.getDependencyTree().printTree(); + print.info(""); + await root.handler.handle(root.uri); } - roots.forEach((root) => { - console.log(root.handler.getResultsList()); - }); - - console.log(uris.map((uArray) => uArray.map((u) => u.toString()))); - process.exitCode = 0; }, }; @@ -187,3 +199,28 @@ function sanitizePackages(packages: string[]) { ); } } + +function validateManifestWithExts( + deployManifest: DeployManifest, + stageToPackageMap: Record +) { + const errors = Object.entries( + stageToPackageMap + ).flatMap(([stageName, deployPackage]) => + deployPackage.manifestExt + ? validate( + deployManifest.stages[stageName].config, + deployPackage.manifestExt + ).errors + : [] + ); + + if (errors.length) { + throw new Error( + [ + `Validation errors encountered while sanitizing DeployManifest format ${deployManifest.format}`, + ...errors.map((error) => error.toString()), + ].join("\n") + ); + } +} diff --git a/packages/cli/src/lib/deploy/asciiTree.ts b/packages/cli/src/lib/deploy/asciiTree.ts new file mode 100644 index 0000000000..81dd3bd3c3 --- /dev/null +++ b/packages/cli/src/lib/deploy/asciiTree.ts @@ -0,0 +1,128 @@ +// https://github.com/aws/jsii/blob/main/packages/oo-ascii-tree/lib/ascii-tree.ts + +export class AsciiTree { + public parent?: AsciiTree; + + private readonly _children = new Array(); + + public constructor(public readonly text?: string, ...children: AsciiTree[]) { + for (const child of children) { + this.add(child); + } + } + + public printTree(output: Printer = process.stdout): void { + let ancestorsPrefix = ""; + + for (const parent of this.ancestors) { + if (parent.level <= 0) { + continue; + } + + if (parent.last) { + ancestorsPrefix += " "; + } else { + ancestorsPrefix += " │"; + } + } + + let myPrefix = ""; + let multilinePrefix = ""; + if (this.level > 0) { + if (this.last) { + if (!this.empty) { + myPrefix += " └─┬ "; + multilinePrefix += " └─┬ "; + } else { + myPrefix += " └── "; + multilinePrefix = " "; + } + } else { + if (!this.empty) { + myPrefix += " ├─┬ "; + multilinePrefix += " │ │ "; + } else { + myPrefix += " ├── "; + multilinePrefix += " │ "; + } + } + } + + if (this.text) { + output.write(ancestorsPrefix); + output.write(myPrefix); + const lines = this.text.split("\n"); + output.write(lines[0]); + output.write("\n"); + + for (const line of lines.splice(1)) { + output.write(ancestorsPrefix); + output.write(multilinePrefix); + output.write(line); + output.write("\n"); + } + } + + for (const child of this._children) { + child.printTree(output); + } + } + + public toString(): string { + let out = ""; + const printer: Printer = { + write: (data: Uint8Array | string) => { + out += data; + return true; + }, + }; + this.printTree(printer); + return out; + } + + public add(...children: AsciiTree[]): void { + for (const child of children) { + child.parent = this; + this._children.push(child); + } + } + + public get children(): AsciiTree[] { + return this._children.map((x) => x); + } + + public get root(): boolean { + return !this.parent; + } + + public get last(): boolean { + if (!this.parent) { + return true; + } + return ( + this.parent.children.indexOf(this) === this.parent.children.length - 1 + ); + } + + public get level(): number { + if (!this.parent) { + return this.text ? 0 : -1; + } + + return this.parent.level + 1; + } + + public get empty(): boolean { + return this.children.length === 0; + } + + public get ancestors(): AsciiTree[] { + if (!this.parent) { + return []; + } + + return [...this.parent.ancestors, this.parent]; + } +} + +export type Printer = Pick; diff --git a/packages/cli/src/lib/deploy/deployer.ts b/packages/cli/src/lib/deploy/deployer.ts index f492970eb7..ef9b5e731f 100644 --- a/packages/cli/src/lib/deploy/deployer.ts +++ b/packages/cli/src/lib/deploy/deployer.ts @@ -1,5 +1,8 @@ /* eslint-disable @typescript-eslint/no-require-imports */ +import { AsciiTree } from "./asciiTree"; + import { Uri } from "@web3api/core-js"; +import { GluegunPrint } from "gluegun"; export interface Deployer { execute(uri: Uri, config?: unknown): Promise; @@ -22,13 +25,17 @@ interface Handler { } abstract class AbstractHandler implements Handler { + private dependencyTree: AsciiTree; private nextHandlers: AbstractHandler[] = []; protected result: string; - constructor(public name: string) {} + constructor(public name: string) { + this.dependencyTree = new AsciiTree(this.name); + } public addNext(handler: AbstractHandler): void { this.nextHandlers.push(handler); + this.dependencyTree.add(handler.dependencyTree); } public async handle(uri: Uri): Promise { @@ -47,6 +54,10 @@ abstract class AbstractHandler implements Handler { }; } + public getDependencyTree(): AsciiTree { + return this.dependencyTree; + } + public getResultsList(): ResultList { return { name: this.name, @@ -60,14 +71,27 @@ export class DeployerHandler extends AbstractHandler { constructor( name: string, private deployer: Deployer, - private config: unknown + private config: unknown, + private printer: GluegunPrint ) { super(name); } public async handle(uri: Uri): Promise { - const nextUri = await this.deployer.execute(uri, this.config); - this.result = nextUri.toString(); - return [nextUri, ...(await super.handle(nextUri))]; + this.printer.info( + `Executing stage: '${this.name}', with URI: '${uri.toString()}'` + ); + + try { + const nextUri = await this.deployer.execute(uri, this.config); + this.result = nextUri.toString(); + + this.printer.success( + `Successfully executed stage '${this.name}'. Result: '${this.result}'` + ); + return [nextUri, ...(await super.handle(nextUri))]; + } catch (e) { + throw new Error(`Failed to execute stage '${this.name}'. Error: ${e}`); + } } } diff --git a/packages/cli/src/lib/deploy/index.ts b/packages/cli/src/lib/deploy/index.ts index abb67ce8cd..0ef8bd95d5 100644 --- a/packages/cli/src/lib/deploy/index.ts +++ b/packages/cli/src/lib/deploy/index.ts @@ -1 +1,10 @@ +import { Deployer } from "./deployer"; + +import { Schema as JsonSchema } from "jsonschema"; + export * from "./deployer"; + +export interface DeployPackage { + deployer: Deployer; + manifestExt: JsonSchema | undefined; +} diff --git a/packages/cli/src/lib/deployers/ipfs/formData.ts b/packages/cli/src/lib/deployers/ipfs/formData.ts index 48efd8b2d4..44a5e31ae7 100644 --- a/packages/cli/src/lib/deployers/ipfs/formData.ts +++ b/packages/cli/src/lib/deployers/ipfs/formData.ts @@ -57,8 +57,6 @@ export function convertDirectoryBlobToFormData( let formData: FormDataEntry[] = []; const files = directoryBlob.files; - console.log(files.map((f) => f.name)); - for (let i = 0; i < files.length; i++) { formData.push(convertFileEntryToFormData(files[i], "")); } diff --git a/packages/cli/src/lib/deployers/ipfs/index.ts b/packages/cli/src/lib/deployers/ipfs/index.ts index b7d86d7c6c..07fca99697 100644 --- a/packages/cli/src/lib/deployers/ipfs/index.ts +++ b/packages/cli/src/lib/deployers/ipfs/index.ts @@ -9,8 +9,8 @@ import { Uri } from "@web3api/core-js"; const isValidUri = (uri: Uri) => uri.authority === "file"; -const resolveBuildDir = (path: string): DirectoryBlob => { - const dirEntry = convertDirectoryToEntry(path); +const resolveBuildDir = (buildDirPath: string): DirectoryBlob => { + const dirEntry = convertDirectoryToEntry(buildDirPath); return { files: [], diff --git a/packages/cli/src/lib/helpers/spinner.ts b/packages/cli/src/lib/helpers/spinner.ts index 4dd49de557..0b0b787dae 100644 --- a/packages/cli/src/lib/helpers/spinner.ts +++ b/packages/cli/src/lib/helpers/spinner.ts @@ -57,3 +57,30 @@ export const step = (spinner: Ora, subject: string, text?: string): unknown => { spinner.start(); return spinner; }; + +export const searchOptional = async ( + loadText: string, + errorText: string, + warningText: string, + execute: (spinner: Ora) => Promise +): Promise => { + const spinner = gluegun.print.spin({ + text: loadText, + stream: process.stdout, + }); + + try { + const result = await execute(spinner); + + if (!result) { + spinner.warn(warningText); + } else { + spinner.succeed(loadText); + } + + return result as T; + } catch (e) { + spinner.fail(`${errorText}: ${e.message}`); + throw e; + } +}; diff --git a/packages/cli/src/lib/manifest/web3api/load.ts b/packages/cli/src/lib/manifest/web3api/load.ts index b8e570004f..49441a0039 100644 --- a/packages/cli/src/lib/manifest/web3api/load.ts +++ b/packages/cli/src/lib/manifest/web3api/load.ts @@ -1,4 +1,4 @@ -import { displayPath, withSpinner, intlMsg } from "../../"; +import { displayPath, withSpinner, intlMsg, searchOptional } from "../../"; import { Web3ApiManifest, @@ -153,6 +153,46 @@ export async function loadDeployManifest( } } +export async function loadDeployManifestExt( + manifestExtPath: string, + quiet = false +): Promise { + const run = (): JsonSchema | undefined => { + const configSchemaPath = path.join( + path.dirname(manifestExtPath), + "/web3api.deploy.ext.json" + ); + + let extSchema: JsonSchema | undefined; + + if (fs.existsSync(configSchemaPath)) { + extSchema = JSON.parse( + fs.readFileSync(configSchemaPath, "utf-8") + ) as JsonSchema; + } + + return extSchema; + }; + + if (quiet) { + return run(); + } else { + manifestExtPath = displayPath(manifestExtPath); + return await searchOptional( + intlMsg.lib_helpers_deployManifestExt_loadText({ path: manifestExtPath }), + intlMsg.lib_helpers_deployManifestExt_loadError({ + path: manifestExtPath, + }), + intlMsg.lib_helpers_deployManifestExt_loadWarning({ + path: manifestExtPath, + }), + async (_spinner) => { + return run(); + } + ); + } +} + export const defaultMetaManifest = ["web3api.meta.yaml", "web3api.meta.yml"]; export async function loadMetaManifest( diff --git a/packages/cli/src/lib/project/Web3ApiProject.ts b/packages/cli/src/lib/project/Web3ApiProject.ts index df5bc36dbf..823d50f214 100644 --- a/packages/cli/src/lib/project/Web3ApiProject.ts +++ b/packages/cli/src/lib/project/Web3ApiProject.ts @@ -14,6 +14,7 @@ import { outputManifest, intlMsg, loadDeployManifest, + loadDeployManifestExt, } from ".."; import { Deployer } from "../deploy"; @@ -26,6 +27,7 @@ import { import { getCommonPath, normalizePath } from "@web3api/os-js"; import regexParser from "regex-parser"; import path from "path"; +import { Schema as JsonSchema } from "jsonschema"; import fs from "fs"; import fsExtra from "fs-extra"; @@ -373,7 +375,9 @@ export class Web3ApiProject extends Project { return this._deployManifest; } - public getDeploymentPackage(packageName: string): Deployer { + public async getDeploymentPackage( + packageName: string + ): Promise<{ deployer: Deployer; manifestExt: JsonSchema | undefined }> { if (!this._deploymentPackagesCached) { throw new Error("Deployment packages have not been cached"); } @@ -382,8 +386,15 @@ export class Web3ApiProject extends Project { `${cacheLayout.deployEnvDir}/${packageName}` ); - // eslint-disable-next-line @typescript-eslint/no-require-imports - return require(cachePath).default as Deployer; + const manifestExtPath = path.join(cachePath, "web3api.deploy.ext.json"); + + const manifestExt = await loadDeployManifestExt(manifestExtPath); + + return { + // eslint-disable-next-line @typescript-eslint/no-require-imports + deployer: require(cachePath).default as Deployer, + manifestExt, + }; } public async cacheDeploymentPackages(packages: string[]): Promise { From 0af8cfbc28e23c34d9e8a084755e381db62ce616 Mon Sep 17 00:00:00 2001 From: namesty Date: Thu, 14 Apr 2022 03:32:52 +0200 Subject: [PATCH 16/41] (chore): added e2e tests --- packages/cli/src/__tests__/e2e/deploy.spec.ts | 82 +++++++++++++++++-- .../project/web3api-deploy-fail-between.yaml | 12 +++ .../web3api-deploy-invalid-config.yaml | 12 +++ .../project/web3api-deploy-no-ext.yaml | 12 +++ .../project/web3api.deploy.fail-between.yaml | 19 +++++ .../web3api.deploy.invalid-config.yaml | 12 +++ .../project/web3api.deploy.no-ext.yaml | 7 ++ .../cli/src/lib/deployers/ipfs-test/index.ts | 12 +++ 8 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 packages/cli/src/__tests__/project/web3api-deploy-fail-between.yaml create mode 100644 packages/cli/src/__tests__/project/web3api-deploy-invalid-config.yaml create mode 100644 packages/cli/src/__tests__/project/web3api-deploy-no-ext.yaml create mode 100644 packages/cli/src/__tests__/project/web3api.deploy.fail-between.yaml create mode 100644 packages/cli/src/__tests__/project/web3api.deploy.invalid-config.yaml create mode 100644 packages/cli/src/__tests__/project/web3api.deploy.no-ext.yaml create mode 100644 packages/cli/src/lib/deployers/ipfs-test/index.ts diff --git a/packages/cli/src/__tests__/e2e/deploy.spec.ts b/packages/cli/src/__tests__/e2e/deploy.spec.ts index 18db8da712..52136e92b3 100644 --- a/packages/cli/src/__tests__/e2e/deploy.spec.ts +++ b/packages/cli/src/__tests__/e2e/deploy.spec.ts @@ -23,7 +23,6 @@ Options: -h, --help Show usage information -m, --manifest-file Path to the Web3API Deploy manifest file (default: web3api.yaml | web3api.yml) -v, --verbose Verbose output (default: false) - -p, --path Path to the build directory `; const setup = async (domainNames: string[]) => { @@ -136,8 +135,8 @@ describe("e2e tests for deploy command", () => { expect(clearStyle(output)).toEqual(HELP); }); - test.only("Successfully deploys the project", async () => { - const { stdout: output, stderr: error } = await runCLI( + test("Successfully deploys the project", async () => { + const { exitCode: code, stdout: output } = await runCLI( { args: ["deploy"], cwd: projectRoot, @@ -145,7 +144,80 @@ describe("e2e tests for deploy command", () => { }, ); - console.log(output) - console.log(error) + const sanitizedOutput = clearStyle(output); + + expect(code).toEqual(0); + expect(sanitizedOutput).toContain( + "Successfully executed stage 'ipfs_deploy'" + ); + expect(sanitizedOutput).toContain( + "Successfully executed stage 'from_deploy'" + ); + expect(sanitizedOutput).toContain( + "Successfully executed stage 'from_deploy2'" + ); + expect(sanitizedOutput).toContain( + "Successfully executed stage 'from_uri'" + ); + }); + + test("Throws and stops chain if error is found", async () => { + const { exitCode: code, stdout: output, stderr } = await runCLI( + { + args: ["deploy", "--manifest-file", "web3api-deploy-fail-between.yaml"], + cwd: projectRoot, + cli: w3Cli, + }, + ); + + const sanitizedOutput = clearStyle(output); + const sanitizedErr = clearStyle(stderr); + + expect(code).toEqual(1); + expect(sanitizedOutput).toContain( + "Successfully executed stage 'ipfs_deploy'" + ); + expect(sanitizedOutput).not.toContain( + "Successfully executed stage 'from_deploy2'" + ); + + expect(sanitizedErr).toContain( + "Failed to execute stage 'from_deploy'" + ); + }); + + test("Throws if manifest ext exists and config property is invalid", async () => { + const { exitCode: code, stderr } = await runCLI( + { + args: ["deploy", "--manifest-file", "web3api-deploy-invalid-config.yaml"], + cwd: projectRoot, + cli: w3Cli, + }, + ); + + const sanitizedErr = clearStyle(stderr); + + expect(code).toEqual(1); + expect(sanitizedErr).toContain("domainName is not of a type(s) string") + }); + + test("Throws and stops chain if error is found", async () => { + const { exitCode: code, stdout: output } = await runCLI( + { + args: ["deploy", "--manifest-file", "web3api-deploy-no-ext.yaml"], + cwd: projectRoot, + cli: w3Cli, + }, + ); + + const sanitizedOutput = clearStyle(output); + + expect(code).toEqual(0); + expect(sanitizedOutput).toContain( + "No manifest extension found in" + ); + expect(sanitizedOutput).toContain( + "Successfully executed stage 'ipfs_test'" + ); }); }); diff --git a/packages/cli/src/__tests__/project/web3api-deploy-fail-between.yaml b/packages/cli/src/__tests__/project/web3api-deploy-fail-between.yaml new file mode 100644 index 0000000000..149bce643c --- /dev/null +++ b/packages/cli/src/__tests__/project/web3api-deploy-fail-between.yaml @@ -0,0 +1,12 @@ +format: 0.0.1-prealpha.8 +name: test-project +build: ./web3api.build.yaml +deploy: ./web3api.deploy.fail-between.yaml +language: wasm/assemblyscript +modules: + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/cli/src/__tests__/project/web3api-deploy-invalid-config.yaml b/packages/cli/src/__tests__/project/web3api-deploy-invalid-config.yaml new file mode 100644 index 0000000000..3c4e6f961d --- /dev/null +++ b/packages/cli/src/__tests__/project/web3api-deploy-invalid-config.yaml @@ -0,0 +1,12 @@ +format: 0.0.1-prealpha.8 +name: test-project +build: ./web3api.build.yaml +deploy: ./web3api.deploy.invalid-config.yaml +language: wasm/assemblyscript +modules: + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/cli/src/__tests__/project/web3api-deploy-no-ext.yaml b/packages/cli/src/__tests__/project/web3api-deploy-no-ext.yaml new file mode 100644 index 0000000000..9aee819f57 --- /dev/null +++ b/packages/cli/src/__tests__/project/web3api-deploy-no-ext.yaml @@ -0,0 +1,12 @@ +format: 0.0.1-prealpha.8 +name: test-project +build: ./web3api.build.yaml +deploy: ./web3api.deploy.no-ext.yaml +language: wasm/assemblyscript +modules: + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/cli/src/__tests__/project/web3api.deploy.fail-between.yaml b/packages/cli/src/__tests__/project/web3api.deploy.fail-between.yaml new file mode 100644 index 0000000000..6f3c346d18 --- /dev/null +++ b/packages/cli/src/__tests__/project/web3api.deploy.fail-between.yaml @@ -0,0 +1,19 @@ +format: 0.0.1-prealpha.1 +stages: + ipfs_deploy: + package: ipfs + uri: file/./build + from_deploy: + package: ens + depends_on: ipfs_deploy + config: + domainName: test1.eth + provider: 'foo' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' + from_deploy2: + package: ens + depends_on: ipfs_deploy + config: + domainName: test2.eth + provider: 'http://localhost:8545' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' \ No newline at end of file diff --git a/packages/cli/src/__tests__/project/web3api.deploy.invalid-config.yaml b/packages/cli/src/__tests__/project/web3api.deploy.invalid-config.yaml new file mode 100644 index 0000000000..37b81baaca --- /dev/null +++ b/packages/cli/src/__tests__/project/web3api.deploy.invalid-config.yaml @@ -0,0 +1,12 @@ +format: 0.0.1-prealpha.1 +stages: + ipfs_deploy: + package: ipfs + uri: file/./build + from_deploy: + package: ens + depends_on: ipfs_deploy + config: + domainName: true + provider: 'http://localhost:8545' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' \ No newline at end of file diff --git a/packages/cli/src/__tests__/project/web3api.deploy.no-ext.yaml b/packages/cli/src/__tests__/project/web3api.deploy.no-ext.yaml new file mode 100644 index 0000000000..5d31532e0f --- /dev/null +++ b/packages/cli/src/__tests__/project/web3api.deploy.no-ext.yaml @@ -0,0 +1,7 @@ +format: 0.0.1-prealpha.1 +stages: + ipfs_test: + package: ipfs-test + uri: file/./build + config: + foo: bar \ No newline at end of file diff --git a/packages/cli/src/lib/deployers/ipfs-test/index.ts b/packages/cli/src/lib/deployers/ipfs-test/index.ts new file mode 100644 index 0000000000..5bb7b5bd53 --- /dev/null +++ b/packages/cli/src/lib/deployers/ipfs-test/index.ts @@ -0,0 +1,12 @@ +import { Deployer } from "../../deploy/deployer"; + +import { Uri } from "@web3api/core-js"; + +class IPFSDeployer implements Deployer { + // eslint-disable-next-line @typescript-eslint/naming-convention + async execute(_: Uri, __: unknown): Promise { + return new Uri(`ipfs/Qm`); + } +} + +export default new IPFSDeployer(); From fd07e899ab6f85f83c2c5a84a5d92e1ba4fd7d28 Mon Sep 17 00:00:00 2001 From: namesty Date: Thu, 14 Apr 2022 05:46:46 +0200 Subject: [PATCH 17/41] (chore): removed unused code. Improved IPFS deployer invalid URI err msg --- packages/cli/src/commands/deploy.ts | 10 ++-------- packages/cli/src/lib/deployers/ens/index.ts | 3 --- packages/cli/src/lib/deployers/ipfs/index.ts | 6 ++++-- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/packages/cli/src/commands/deploy.ts b/packages/cli/src/commands/deploy.ts index d71f3aea7b..2aab2a9ee5 100644 --- a/packages/cli/src/commands/deploy.ts +++ b/packages/cli/src/commands/deploy.ts @@ -36,19 +36,15 @@ export default { const { filesystem, parameters, print } = toolbox; // Options - const { h, m, v, n, c } = parameters.options; - let { help, manifestFile, verbose, name, cid } = parameters.options; + const { h, m, v } = parameters.options; + let { help, manifestFile, verbose } = parameters.options; help = help || h; verbose = verbose || v; manifestFile = manifestFile || m; - name = name || n; - cid = cid || c; // Validate Params const paramsValid = validateDeployParams(print, { - name, - cid, manifestFile, }); @@ -160,8 +156,6 @@ function validateDeployParams( print: GluegunPrint, params: { manifestFile: unknown; - name: unknown; - cid: unknown; } ): boolean { const { manifestFile } = params; diff --git a/packages/cli/src/lib/deployers/ens/index.ts b/packages/cli/src/lib/deployers/ens/index.ts index 17d17c86b2..23c60c5b65 100644 --- a/packages/cli/src/lib/deployers/ens/index.ts +++ b/packages/cli/src/lib/deployers/ens/index.ts @@ -10,9 +10,6 @@ const contentHash = require("content-hash"); const ENS = require("@ensdomains/ensjs"); class ENSPublisher implements Deployer { - blockchain = "Ethereum"; - name = "ens"; - async execute( uri: Uri, config: { diff --git a/packages/cli/src/lib/deployers/ipfs/index.ts b/packages/cli/src/lib/deployers/ipfs/index.ts index 07fca99697..fce0b36ffb 100644 --- a/packages/cli/src/lib/deployers/ipfs/index.ts +++ b/packages/cli/src/lib/deployers/ipfs/index.ts @@ -7,7 +7,7 @@ import FormData from "form-data"; import axios from "axios"; import { Uri } from "@web3api/core-js"; -const isValidUri = (uri: Uri) => uri.authority === "file"; +const isValidUri = (uri: Uri) => uri.authority === "fs"; const resolveBuildDir = (buildDirPath: string): DirectoryBlob => { const dirEntry = convertDirectoryToEntry(buildDirPath); @@ -21,7 +21,9 @@ const resolveBuildDir = (buildDirPath: string): DirectoryBlob => { class IPFSDeployer implements Deployer { async execute(uri: Uri, config?: { gatewayUri: string }): Promise { if (!isValidUri(uri)) { - throw new Error("Invalid URI"); + throw new Error( + `IPFS Deployer error: Invalid URI: ${uri.toString()}. Supplied URI needs to be a Filesystem URI, example: fs/./build` + ); } const path = uri.path; From ae21ede20004d915a98622d7878eee147065d990 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 18 Apr 2022 12:45:39 -0700 Subject: [PATCH 18/41] minor fixes --- packages/cli/package.json | 6 +- .../src/__tests__/Web3ApiClient.spec.ts | 2 +- .../0.0.1-prealpha.7_to_0.0.1-prealpha.8.ts | 1 - yarn.lock | 1187 ++++++++++++++--- 4 files changed, 979 insertions(+), 217 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index 1820dbcd4a..92b7b07e10 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -42,9 +42,9 @@ "@web3api/schema-compose": "0.0.1-prealpha.71", "@web3api/schema-parse": "0.0.1-prealpha.71", "ethers": "5.6.2", - "@ensdomains/ensjs": "^2.0.1", - "content-hash": "^2.5.2", - "form-data": "^4.0.0", + "@ensdomains/ensjs": "2.0.1", + "content-hash": "2.5.2", + "form-data": "4.0.0", "assemblyscript": "0.19.1", "axios": "0.21.2", "chalk": "4.1.0", diff --git a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts index 43f69c59ec..addb07de8e 100644 --- a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts +++ b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts @@ -948,7 +948,7 @@ describe("Web3ApiClient", () => { ).toBe(true); }); - it.only("simple-storage", async () => { + it("simple-storage", async () => { const api = await buildAndDeployApi( `${GetPathToTestApis()}/simple-storage`, ipfsProvider, diff --git a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.7_to_0.0.1-prealpha.8.ts b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.7_to_0.0.1-prealpha.8.ts index 74b76f9ecc..f7cd3cd375 100644 --- a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.7_to_0.0.1-prealpha.8.ts +++ b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.7_to_0.0.1-prealpha.8.ts @@ -8,6 +8,5 @@ export function migrate(old: OldManifest): NewManifest { ...old, __type: "Web3ApiManifest", format: "0.0.1-prealpha.8", - name: "Unnamed", }; } diff --git a/yarn.lock b/yarn.lock index 9d1b4b12ad..d31d117f84 100644 --- a/yarn.lock +++ b/yarn.lock @@ -185,7 +185,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.4.5", "@babel/core@^7.7.5": +"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.4.5", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.8.0": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.9.tgz#6bae81a06d95f4d0dec5bb9d74bbc1f58babdcfe" integrity sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw== @@ -206,7 +206,7 @@ json5 "^2.2.1" semver "^6.3.0" -"@babel/generator@^7.12.13", "@babel/generator@^7.17.9", "@babel/generator@^7.4.0", "@babel/generator@^7.4.4", "@babel/generator@^7.9.0": +"@babel/generator@^7.12.13", "@babel/generator@^7.17.9", "@babel/generator@^7.4.0", "@babel/generator@^7.4.4", "@babel/generator@^7.7.2", "@babel/generator@^7.9.0": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.9.tgz#f4af9fd38fa8de143c29fce3f71852406fc1e2fc" integrity sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ== @@ -751,7 +751,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.16.7": +"@babel/plugin-syntax-typescript@^7.16.7", "@babel/plugin-syntax-typescript@^7.7.2": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== @@ -1403,9 +1403,9 @@ regenerator-runtime "^0.13.4" "@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": - version "7.17.8" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.8.tgz#3e56e4aff81befa55ac3ac6a0967349fd1c5bca2" - integrity sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA== + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72" + integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== dependencies: regenerator-runtime "^0.13.4" @@ -1433,7 +1433,7 @@ globals "^11.1.0" lodash "^4.17.19" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.7.0", "@babel/traverse@^7.9.0": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2", "@babel/traverse@^7.9.0": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d" integrity sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw== @@ -1479,11 +1479,6 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@colors/colors@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" - integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== - "@cspotcode/source-map-consumer@0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" @@ -1635,7 +1630,7 @@ "@ethersproject/properties" ">=5.0.0-beta.131" "@ethersproject/strings" ">=5.0.0-beta.130" -"@ethersproject/abi@5.6.0", "@ethersproject/abi@^5.0.0", "@ethersproject/abi@^5.6.0": +"@ethersproject/abi@5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.0.tgz#ea07cbc1eec2374d32485679c12408005895e9f3" integrity sha512-AhVByTwdXCc2YQ20v300w6KVHle9g2OFc28ZAFCPnJyEpkv1xKXjZcSTgWOlv1i+0dqlgF8RCF2Rn2KC1t+1Vg== @@ -1650,6 +1645,21 @@ "@ethersproject/properties" "^5.6.0" "@ethersproject/strings" "^5.6.0" +"@ethersproject/abi@5.6.1", "@ethersproject/abi@^5.0.0", "@ethersproject/abi@^5.6.0": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.1.tgz#f7de888edeb56b0a657b672bdd1b3a1135cd14f7" + integrity sha512-0cqssYh6FXjlwKWBmLm3+zH2BNARoS5u/hxbz+LpQmcDB3w0W553h2btWui1/uZp2GBM/SI3KniTuMcYyHpA5w== + dependencies: + "@ethersproject/address" "^5.6.0" + "@ethersproject/bignumber" "^5.6.0" + "@ethersproject/bytes" "^5.6.0" + "@ethersproject/constants" "^5.6.0" + "@ethersproject/hash" "^5.6.0" + "@ethersproject/keccak256" "^5.6.0" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/strings" "^5.6.0" + "@ethersproject/abstract-provider@5.6.0", "@ethersproject/abstract-provider@^5.0.0", "@ethersproject/abstract-provider@^5.0.3", "@ethersproject/abstract-provider@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz#0c4ac7054650dbd9c476cf5907f588bbb6ef3061" @@ -1814,13 +1824,20 @@ resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.6.0.tgz#d7db1bfcc22fd2e4ab574cba0bb6ad779a9a3e7a" integrity sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg== -"@ethersproject/networks@5.6.1", "@ethersproject/networks@^5.0.0", "@ethersproject/networks@^5.0.3", "@ethersproject/networks@^5.6.0": +"@ethersproject/networks@5.6.1": version "5.6.1" resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.1.tgz#7a21ed1f83e86121737b16841961ec99ccf5c9c7" integrity sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg== dependencies: "@ethersproject/logger" "^5.6.0" +"@ethersproject/networks@5.6.2", "@ethersproject/networks@^5.0.0", "@ethersproject/networks@^5.0.3", "@ethersproject/networks@^5.6.0": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.2.tgz#2bacda62102c0b1fcee408315f2bed4f6fbdf336" + integrity sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA== + dependencies: + "@ethersproject/logger" "^5.6.0" + "@ethersproject/pbkdf2@5.6.0", "@ethersproject/pbkdf2@^5.0.0", "@ethersproject/pbkdf2@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz#04fcc2d7c6bff88393f5b4237d906a192426685a" @@ -1861,7 +1878,7 @@ bech32 "1.1.4" ws "7.2.3" -"@ethersproject/providers@5.6.2", "@ethersproject/providers@^5.0.0": +"@ethersproject/providers@5.6.2": version "5.6.2" resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.2.tgz#b9807b1c8c6f59fa2ee4b3cf6519724d07a9f422" integrity sha512-6/EaFW/hNWz+224FXwl8+HdMRzVHt8DpPmu5MZaIQqx/K/ELnC9eY236SMV7mleCM3NnEArFwcAAxH5kUUgaRg== @@ -1886,6 +1903,31 @@ bech32 "1.1.4" ws "7.4.6" +"@ethersproject/providers@5.6.4", "@ethersproject/providers@^5.0.0": + version "5.6.4" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.4.tgz#1a49c211b57b0b2703c320819abbbfa35c83dff7" + integrity sha512-WAdknnaZ52hpHV3qPiJmKx401BLpup47h36Axxgre9zT+doa/4GC/Ne48ICPxTm0BqndpToHjpLP1ZnaxyE+vw== + dependencies: + "@ethersproject/abstract-provider" "^5.6.0" + "@ethersproject/abstract-signer" "^5.6.0" + "@ethersproject/address" "^5.6.0" + "@ethersproject/basex" "^5.6.0" + "@ethersproject/bignumber" "^5.6.0" + "@ethersproject/bytes" "^5.6.0" + "@ethersproject/constants" "^5.6.0" + "@ethersproject/hash" "^5.6.0" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/networks" "^5.6.0" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/random" "^5.6.0" + "@ethersproject/rlp" "^5.6.0" + "@ethersproject/sha2" "^5.6.0" + "@ethersproject/strings" "^5.6.0" + "@ethersproject/transactions" "^5.6.0" + "@ethersproject/web" "^5.6.0" + bech32 "1.1.4" + ws "7.4.6" + "@ethersproject/random@5.6.0", "@ethersproject/random@^5.0.0", "@ethersproject/random@^5.0.3", "@ethersproject/random@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.6.0.tgz#1505d1ab6a250e0ee92f436850fa3314b2cb5ae6" @@ -2147,11 +2189,11 @@ tslib "~2.1.0" "@graphql-tools/import@^6.2.6": - version "6.6.9" - resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.6.9.tgz#53e1517074c756b5191d23d4f1528246913d44ba" - integrity sha512-sKaLqvPmNLQlY4te+nnBhRrf5WBISoiyVkbriCLz0kHw805iHdJaU2KxUoHsRTR7WlYq0g9gzB0oVaRh99Q5aA== + version "6.6.12" + resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.6.12.tgz#73e7d43124e1ac0065f5118da8375b626fb9ad54" + integrity sha512-M0detzy3ihJGJbo7MZ6j02198o2nBhiY2MpnWEMRtUMgmZgz5ZTctK3lIxMsd+6LU96m+mc1i2MNIruTHQ6czw== dependencies: - "@graphql-tools/utils" "8.6.5" + "@graphql-tools/utils" "8.6.8" resolve-from "5.0.0" tslib "~2.3.0" @@ -2187,12 +2229,12 @@ "@graphql-tools/utils" "^7.7.0" tslib "~2.2.0" -"@graphql-tools/merge@8.2.6": - version "8.2.6" - resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.6.tgz#7fb615fa9c143c3151ff025e501d52bd48186d19" - integrity sha512-dkwTm4czMISi/Io47IVvq2Fl9q4TIGKpJ0VZjuXYdEFkECyH6A5uwxZfPVandZG+gQs8ocFFoa6RisiUJLZrJw== +"@graphql-tools/merge@8.2.9": + version "8.2.9" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.9.tgz#f4bb6ca58d0d89dbfa4fded6a1457bb359de1450" + integrity sha512-mHRrqMc1NTL6MALBQK1DmAzSxJIKoaCaW7ZCk5bRGzVj/MNQz3OsqlDb/+t9/ONT0V+WI/uxBFsrLMwa4p6L7A== dependencies: - "@graphql-tools/utils" "8.6.5" + "@graphql-tools/utils" "8.6.8" tslib "~2.3.0" "@graphql-tools/merge@^6.2.12": @@ -2214,12 +2256,12 @@ value-or-promise "1.0.6" "@graphql-tools/schema@^8.0.2": - version "8.3.6" - resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.6.tgz#80cfe3eba53eb6390a60a30078d7efbdaa5cc0b7" - integrity sha512-7tWYRQ8hB/rv2zAtv2LtnQl4UybyJPtRz/VLKRmgi7+F5t8iYBahmmsxMDAYMWMmWMqEDiKk54TvAes+J069rQ== + version "8.3.9" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.9.tgz#2b83464a0ef083c92d7076da0fa5939f2f5a1e34" + integrity sha512-9YFCzn0sYAGTWhZrVYY/neK5cie3s0dNm7Qq38tkhOh2ME5BtHW/8ZIq+UrLGKsBYwa+Qjb/UojGWUm2yG/z6Q== dependencies: - "@graphql-tools/merge" "8.2.6" - "@graphql-tools/utils" "8.6.5" + "@graphql-tools/merge" "8.2.9" + "@graphql-tools/utils" "8.6.8" tslib "~2.3.0" value-or-promise "1.0.11" @@ -2255,10 +2297,10 @@ dependencies: tslib "~2.3.0" -"@graphql-tools/utils@8.6.5": - version "8.6.5" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.6.5.tgz#ac04571b03f854c7a938b2ab700516a6c6d32335" - integrity sha512-mjOtaWiS2WIqRz/cq5gaeM3sVrllcu2xbtHROw1su1v3xWa3D3dKgn8Lrl7+tvWs5WUVySsBss/VZ3WdoPkCrA== +"@graphql-tools/utils@8.6.8": + version "8.6.8" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.6.8.tgz#a0824ed5810f66c504df4e97c5900786ac0c260e" + integrity sha512-EdUUeKi/wp/UvuknyINpQ/uXDqTM3qxPPPDIq5RpfW0zQOeCvbZcx8xHoMox0TYKvKtg3zoB7aprUtoW+iZLxw== dependencies: tslib "~2.3.0" @@ -2361,6 +2403,18 @@ jest-util "^26.6.2" slash "^3.0.0" +"@jest/console@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" + integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + "@jest/core@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/core/-/core-24.9.0.tgz#2ceccd0b93181f9c4850e74f2a9ad43d351369c4" @@ -2429,6 +2483,40 @@ slash "^3.0.0" strip-ansi "^6.0.0" +"@jest/core@^27.4.2", "@jest/core@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" + integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/reporters" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^27.5.1" + jest-config "^27.5.1" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-resolve-dependencies "^27.5.1" + jest-runner "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + jest-watcher "^27.5.1" + micromatch "^4.0.4" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + "@jest/environment@^24.3.0", "@jest/environment@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" @@ -2449,6 +2537,16 @@ "@types/node" "*" jest-mock "^26.6.2" +"@jest/environment@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" + integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== + dependencies: + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + "@jest/fake-timers@^24.3.0", "@jest/fake-timers@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" @@ -2470,6 +2568,18 @@ jest-mock "^26.6.2" jest-util "^26.6.2" +"@jest/fake-timers@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" + integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== + dependencies: + "@jest/types" "^27.5.1" + "@sinonjs/fake-timers" "^8.0.1" + "@types/node" "*" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-util "^27.5.1" + "@jest/globals@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.6.2.tgz#5b613b78a1aa2655ae908eba638cc96a20df720a" @@ -2479,6 +2589,15 @@ "@jest/types" "^26.6.2" expect "^26.6.2" +"@jest/globals@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" + integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/types" "^27.5.1" + expect "^27.5.1" + "@jest/reporters@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-24.9.0.tgz#86660eff8e2b9661d042a8e98a028b8d631a5b43" @@ -2538,6 +2657,37 @@ optionalDependencies: node-notifier "^8.0.0" +"@jest/reporters@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" + integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-haste-map "^27.5.1" + jest-resolve "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.1.0" + "@jest/source-map@^24.3.0", "@jest/source-map@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" @@ -2556,6 +2706,15 @@ graceful-fs "^4.2.4" source-map "^0.6.0" +"@jest/source-map@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" + integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.9" + source-map "^0.6.0" + "@jest/test-result@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" @@ -2575,6 +2734,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-result@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" + integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== + dependencies: + "@jest/console" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + "@jest/test-sequencer@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz#f8f334f35b625a4f2f355f2fe7e6036dad2e6b31" @@ -2596,6 +2765,16 @@ jest-runner "^26.6.3" jest-runtime "^26.6.3" +"@jest/test-sequencer@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" + integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== + dependencies: + "@jest/test-result" "^27.5.1" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-runtime "^27.5.1" + "@jest/transform@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" @@ -2639,6 +2818,27 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/transform@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" + integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.5.1" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-regex-util "^27.5.1" + jest-util "^27.5.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + "@jest/types@^24.3.0", "@jest/types@^24.9.0": version "24.9.0" resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" @@ -2669,6 +2869,17 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + "@jridgewell/resolve-uri@^3.0.3": version "3.0.5" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" @@ -3737,6 +3948,13 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@svgr/babel-plugin-add-jsx-attribute@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1" @@ -3922,7 +4140,7 @@ resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc" integrity sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig== -"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.0", "@types/babel__core@^7.1.7": +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.0", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.7": version "7.1.19" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== @@ -3949,9 +4167,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" - integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.17.0.tgz#7a9b80f712fe2052bc20da153ff1e552404d8e4b" + integrity sha512-r8aveDbd+rzGP+ykSdF3oPuTVRWRfbBiHl0rVDM2yNEmSMXfkObQLV46b4RnCv3Lra51OlfnZhkkFaDl2MIRaA== dependencies: "@babel/types" "^7.3.0" @@ -4066,6 +4284,14 @@ jest-diff "^25.2.1" pretty-format "^25.2.1" +"@types/jest@27.0.3": + version "27.0.3" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.0.3.tgz#0cf9dfe9009e467f70a342f0f94ead19842a783a" + integrity sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg== + dependencies: + jest-diff "^27.0.0" + pretty-format "^27.0.0" + "@types/js-yaml@3.11.1": version "3.11.1" resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.11.1.tgz#ac5bab26be5f9c6f74b6b23420f2cfa5a7a6ba40" @@ -4102,9 +4328,9 @@ integrity sha512-wH6Tu9mbiOt0n5EvdoWy0VGQaJMHfLIxY/6wS0xLC7CV1taM6gESEzcYy0ZlWvxxiiljYvfDIvz4hHbUUDRlhw== "@types/node@*": - version "17.0.23" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da" - integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw== + version "17.0.25" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.25.tgz#527051f3c2f77aa52e5dc74e45a3da5fb2301448" + integrity sha512-wANk6fBrUwdpY4isjWrKTufkrXdu1D2YHCot2fD/DfWxF5sMrVSA+KN7ydckvaTCh0HiqX9IVl0L5/ZoXg5M7w== "@types/node@12.0.0": version "12.0.0" @@ -4116,10 +4342,15 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.26.tgz#213e153babac0ed169d44a6d919501e68f59dea9" integrity sha512-UmUm94/QZvU5xLcUlNR8hA7Ac+fGpO1EG/a8bcWVz0P0LqtxFmun9Y2bbtuckwGboWJIT70DoWq1r3hb56n3DA== +"@types/node@16.11.11": + version "16.11.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.11.tgz#6ea7342dfb379ea1210835bada87b3c512120234" + integrity sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw== + "@types/node@^12.12.6": - version "12.20.47" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.47.tgz#ca9237d51f2a2557419688511dab1c8daf475188" - integrity sha512-BzcaRsnFuznzOItW1WpQrDHM7plAa7GIDMZ6b5pnMbkqEtM/6WCOhvZar39oeMQP79gwvFUWjjptE7/KGcNqFg== + version "12.20.48" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.48.tgz#55f70bd432b6515828c0298689776861b90ca4fa" + integrity sha512-4kxzqkrpwYtn6okJUcb2lfUu9ilnb3yhUOH6qX3nug8D2DupZ2drIkff2yJzYcNJVl3begnlcaBJ7tqiTTzjnQ== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -4139,9 +4370,9 @@ "@types/node" "*" "@types/prettier@^2.0.0", "@types/prettier@^2.1.5": - version "2.4.4" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17" - integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA== + version "2.6.0" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.0.tgz#efcbd41937f9ae7434c714ab698604822d890759" + integrity sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw== "@types/prop-types@*": version "15.7.5" @@ -4168,22 +4399,13 @@ "@types/react" "*" "@types/react-test-renderer@>=16.9.0": - version "17.0.1" - resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz#3120f7d1c157fba9df0118dae20cb0297ee0e06b" - integrity sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw== + version "18.0.0" + resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz#7b7f69ca98821ea5501b21ba24ea7b6139da2243" + integrity sha512-C7/5FBJ3g3sqUahguGi03O79b8afNeSD6T8/GU50oQrJCU0bVCCGQHaGKUbg2Ce8VQEEqTw8/HiS6lXHHdgkdQ== dependencies: "@types/react" "*" -"@types/react@*", "@types/react@>=16.9.0": - version "17.0.43" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.43.tgz#4adc142887dd4a2601ce730bc56c3436fdb07a55" - integrity sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/react@16.9.0": +"@types/react@*", "@types/react@16.9.0", "@types/react@>=16.9.0": version "16.9.0" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.0.tgz#27434f16d889a335eb4626d1f1e67eda54039e5b" integrity sha512-eOct1hyZI9YZf/eqNlYu7jxA9qyTw1EGXruAJhHhBDBpc00W0C1vwlnh+hkOf7UFZkNK+UxnFBpwAZe3d7XJhQ== @@ -4259,6 +4481,13 @@ dependencies: "@types/yargs-parser" "*" +"@types/yargs@^16.0.0": + version "16.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + dependencies: + "@types/yargs-parser" "*" + "@typescript-eslint/eslint-plugin@4.11.1": version "4.11.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.11.1.tgz#7579c6d17ad862154c10bc14b40e5427b729e209" @@ -4580,9 +4809,9 @@ JSONStream@^1.0.4: through ">=2.2.7 <3" abab@^2.0.0, abab@^2.0.3, abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== abbrev@1: version "1.1.1" @@ -4837,6 +5066,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + any-promise@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" @@ -5046,13 +5280,14 @@ array-unique@^0.3.2: integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= array.prototype.flat@^1.2.1, array.prototype.flat@^1.2.3: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" - integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== + version "1.3.0" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" + integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.19.0" + es-abstract "^1.19.2" + es-shim-unscopables "^1.0.0" arrify@^1.0.1: version "1.0.1" @@ -5179,22 +5414,12 @@ async-limiter@~1.0.0: integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== async@^2.1.2, async@^2.6.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== dependencies: lodash "^4.17.14" -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" @@ -5417,6 +5642,20 @@ babel-jest@^26.6.3: graceful-fs "^4.2.4" slash "^3.0.0" +babel-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== + dependencies: + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + babel-loader@8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" @@ -5466,7 +5705,7 @@ babel-plugin-istanbul@^5.1.0: istanbul-lib-instrument "^3.3.0" test-exclude "^5.2.3" -babel-plugin-istanbul@^6.0.0: +babel-plugin-istanbul@^6.0.0, babel-plugin-istanbul@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== @@ -5494,6 +5733,16 @@ babel-plugin-jest-hoist@^26.6.2: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + babel-plugin-macros@2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" @@ -5867,6 +6116,14 @@ babel-preset-jest@^26.6.2: babel-plugin-jest-hoist "^26.6.2" babel-preset-current-node-syntax "^1.0.0" +babel-preset-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== + dependencies: + babel-plugin-jest-hoist "^27.5.1" + babel-preset-current-node-syntax "^1.0.0" + babel-preset-react-app@^9.1.2: version "9.1.2" resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-9.1.2.tgz#54775d976588a8a6d1a99201a702befecaf48030" @@ -6306,7 +6563,7 @@ browserslist@^3.2.6: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.5.2, browserslist@^4.6.2, browserslist@^4.6.4, browserslist@^4.9.1: +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.17.5, browserslist@^4.20.2, browserslist@^4.5.2, browserslist@^4.6.2, browserslist@^4.6.4, browserslist@^4.9.1: version "4.20.2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== @@ -6630,7 +6887,7 @@ camelcase@^4.1.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= -camelcase@^6.0.0: +camelcase@^6.0.0, camelcase@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -6646,9 +6903,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001035, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001317: - version "1.0.30001325" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001325.tgz#2b4ad19b77aa36f61f2eaf72e636d7481d55e606" - integrity sha512-sB1bZHjseSjDtijV1Hb7PB2Zd58Kyx+n/9EotvZ4Qcz2K3d0lWB8dB4nb8wN/TsOGFq3UuAm0zQZNQ4SoR7TrQ== + version "1.0.30001332" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd" + integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== capture-exit@^2.0.0: version "2.0.0" @@ -6798,6 +7055,11 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +ci-info@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== + cids@^0.7.1: version "0.7.5" resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" @@ -6843,6 +7105,11 @@ cjs-module-lexer@^0.6.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz#4186fcca0eae175970aee870b9fe2d6cf8d5655f" integrity sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw== +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + class-is@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" @@ -7088,11 +7355,6 @@ color@^3.0.0: color-convert "^1.9.3" color-string "^1.6.0" -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, colors@^1.3.3: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" @@ -7426,17 +7688,17 @@ copyfiles@2.4.1: yargs "^16.1.0" core-js-compat@^3.0.0, core-js-compat@^3.20.2, core-js-compat@^3.21.0, core-js-compat@^3.6.2: - version "3.21.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.1.tgz#cac369f67c8d134ff8f9bd1623e3bc2c42068c82" - integrity sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g== + version "3.22.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.0.tgz#7ce17ab57c378be2c717c7c8ed8f82a50a25b3e4" + integrity sha512-WwA7xbfRGrk8BGaaHlakauVXrlYmAIkk8PNGb1FDQS+Rbrewc3pgFfwJFRw6psmJVAll7Px9UHRYE16oRQnwAQ== dependencies: - browserslist "^4.19.1" + browserslist "^4.20.2" semver "7.0.0" core-js-pure@^3.20.2: - version "3.21.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.1.tgz#8c4d1e78839f5f46208de7230cebfb72bc3bdb51" - integrity sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ== + version "3.22.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.0.tgz#0eaa54b6d1f4ebb4d19976bb4916dfad149a3747" + integrity sha512-ylOC9nVy0ak1N+fPIZj00umoZHgUVqmucklP5RT5N+vJof38klKn8Ze6KGyvchdClvEBr6LcQqJpI216LUMqYA== core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5: version "2.6.12" @@ -7444,9 +7706,9 @@ core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.5.0: - version "3.21.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.21.1.tgz#f2e0ddc1fc43da6f904706e8e955bc19d06a0d94" - integrity sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig== + version "3.22.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.0.tgz#b52007870c5e091517352e833b77f0b2d2b259f3" + integrity sha512-8h9jBweRjMiY+ORO7bdWSeWfHhLPO7whobj7Z2Bl0IDo00C228EdGgH7FE4jGumbEjzcFfkfW8bXgdkEDhnwHQ== core-util-is@1.0.2: version "1.0.2" @@ -7880,11 +8142,6 @@ csv-stringify@^5.6.2: resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-5.6.5.tgz#c6d74badda4b49a79bf4e72f91cce1e33b94de00" integrity sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A== -cycle@1.0.x: - version "1.0.3" - resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" - integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI= - cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -7950,7 +8207,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6. dependencies: ms "2.0.0" -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -8047,11 +8304,12 @@ defer-to-connect@^1.0.1: integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== define-properties@^1.1.2, 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== + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== dependencies: - object-keys "^1.0.12" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" define-property@^0.2.5: version "0.2.5" @@ -8192,6 +8450,11 @@ diff-sequences@^26.6.2: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== +diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== + diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -8311,9 +8574,9 @@ dom-serializer@0: entities "^2.0.0" dom-serializer@^1.0.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" - integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== + version "1.4.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== dependencies: domelementtype "^2.0.1" domhandler "^4.2.0" @@ -8460,9 +8723,9 @@ electron-fetch@^1.7.2: encoding "^0.1.13" electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.47, electron-to-chromium@^1.4.84: - version "1.4.103" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz#abfe376a4d70fa1e1b4b353b95df5d6dfd05da3a" - integrity sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg== + version "1.4.111" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.111.tgz#897613f6504f3f17c9381c7499a635b413e4df4e" + integrity sha512-/s3+fwhKf1YK4k7btOImOzCQLpUjS6MaPf0ODTNuT4eTM1Bg4itBpLkydhOzJmpmH6Z9eXFyuuK5czsmzRzwtw== elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" @@ -8482,6 +8745,11 @@ emittery@^0.7.1: resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82" integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ== +emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + emoji-regex@^7.0.1, emoji-regex@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -8613,10 +8881,10 @@ error@^7.0.0: dependencies: string-template "~0.2.1" -es-abstract@^1.17.2, es-abstract@^1.18.5, es-abstract@^1.19.0, es-abstract@^1.19.1: - version "1.19.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.2.tgz#8f7b696d8f15b167ae3640b4060670f3d054143f" - integrity sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w== +es-abstract@^1.17.2, es-abstract@^1.18.5, es-abstract@^1.19.1, es-abstract@^1.19.2: + version "1.19.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.5.tgz#a2cb01eb87f724e815b278b0dd0d00f36ca9a7f1" + integrity sha512-Aa2G2+Rd3b6kxEUKTF4TaW67czBLyAv3z7VOhYRU50YBx+bbsYZ9xQP4lMNazePuFlybXI0V4MruPos7qUo5fA== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" @@ -8629,7 +8897,7 @@ es-abstract@^1.17.2, es-abstract@^1.18.5, es-abstract@^1.19.0, es-abstract@^1.19 is-callable "^1.2.4" is-negative-zero "^2.0.2" is-regex "^1.1.4" - is-shared-array-buffer "^1.0.1" + is-shared-array-buffer "^1.0.2" is-string "^1.0.7" is-weakref "^1.0.2" object-inspect "^1.12.0" @@ -8639,6 +8907,13 @@ es-abstract@^1.17.2, es-abstract@^1.18.5, es-abstract@^1.19.0, es-abstract@^1.19 string.prototype.trimstart "^1.0.4" unbox-primitive "^1.0.1" +es-shim-unscopables@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" + integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + dependencies: + has "^1.0.3" + 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" @@ -8649,9 +8924,9 @@ es-to-primitive@^1.2.1: is-symbol "^1.0.2" es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.59, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.59" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.59.tgz#71038939730eb6f4f165f1421308fb60be363bc6" - integrity sha512-cOgyhW0tIJyQY1Kfw6Kr0viu9ZlUctVchRMZ7R0HiH3dxTSp5zJDLecwxUqPUrGKMsgBI1wd1FL+d9Jxfi4cLw== + version "0.10.60" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.60.tgz#e8060a86472842b93019c31c34865012449883f4" + integrity sha512-jpKNXIt60htYG59/9FGf2PYT3pwMpnEbNKysU+k/4FGwyGtMotOvcZOuW+EmXXYASRqYSXQfGL5cVIthOTgbkg== dependencies: es6-iterator "^2.0.3" es6-symbol "^3.1.3" @@ -9237,7 +9512,7 @@ ethers@5.0.7: "@ethersproject/web" "^5.0.0" "@ethersproject/wordlists" "^5.0.0" -ethers@5.6.2, ethers@^5.0.13: +ethers@5.6.2: version "5.6.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.6.2.tgz#e75bac7f038c5e0fdde667dba62fc223924143a2" integrity sha512-EzGCbns24/Yluu7+ToWnMca3SXJ1Jk1BvWB7CCmVNxyOeM4LLvw2OLuIHhlkhQk1dtOcj9UMsdkxUh8RiG1dxQ== @@ -9273,6 +9548,42 @@ ethers@5.6.2, ethers@^5.0.13: "@ethersproject/web" "5.6.0" "@ethersproject/wordlists" "5.6.0" +ethers@^5.0.13: + version "5.6.4" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.6.4.tgz#23629e9a7d4bc5802dfb53d4da420d738744b53c" + integrity sha512-62UIfxAQXdf67TeeOaoOoPctm5hUlYgfd0iW3wxfj7qRYKDcvvy0f+sJ3W2/Pyx77R8dblvejA8jokj+lS+ATQ== + dependencies: + "@ethersproject/abi" "5.6.1" + "@ethersproject/abstract-provider" "5.6.0" + "@ethersproject/abstract-signer" "5.6.0" + "@ethersproject/address" "5.6.0" + "@ethersproject/base64" "5.6.0" + "@ethersproject/basex" "5.6.0" + "@ethersproject/bignumber" "5.6.0" + "@ethersproject/bytes" "5.6.1" + "@ethersproject/constants" "5.6.0" + "@ethersproject/contracts" "5.6.0" + "@ethersproject/hash" "5.6.0" + "@ethersproject/hdnode" "5.6.0" + "@ethersproject/json-wallets" "5.6.0" + "@ethersproject/keccak256" "5.6.0" + "@ethersproject/logger" "5.6.0" + "@ethersproject/networks" "5.6.2" + "@ethersproject/pbkdf2" "5.6.0" + "@ethersproject/properties" "5.6.0" + "@ethersproject/providers" "5.6.4" + "@ethersproject/random" "5.6.0" + "@ethersproject/rlp" "5.6.0" + "@ethersproject/sha2" "5.6.0" + "@ethersproject/signing-key" "5.6.0" + "@ethersproject/solidity" "5.6.0" + "@ethersproject/strings" "5.6.0" + "@ethersproject/transactions" "5.6.0" + "@ethersproject/units" "5.6.0" + "@ethersproject/wallet" "5.6.0" + "@ethersproject/web" "5.6.0" + "@ethersproject/wordlists" "5.6.0" + ethjs-unit@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" @@ -9456,6 +9767,16 @@ expect@^26.6.2: jest-message-util "^26.6.2" jest-regex-util "^26.0.0" +expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== + dependencies: + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + explain-error@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/explain-error/-/explain-error-1.0.4.tgz#a793d3ac0cad4c6ab571e9968fbbab6cb2532929" @@ -9598,11 +9919,6 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== -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" @@ -10092,7 +10408,7 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@^2.1.2, fsevents@~2.3.1, fsevents@~2.3.2: +fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.1, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -10107,6 +10423,11 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +functions-have-names@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21" + integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA== + ganache-cli@^6.1.0: version "6.12.2" resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.12.2.tgz#c0920f7db0d4ac062ffe2375cb004089806f627a" @@ -10486,7 +10807,7 @@ got@^7.1.0: url-parse-lax "^1.0.0" url-to-options "^1.0.1" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.4: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.4, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== @@ -10620,6 +10941,13 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + has-symbol-support-x@^1.4.1: version "1.4.2" resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" @@ -10952,9 +11280,9 @@ https-browserify@^1.0.0: integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= 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== + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== dependencies: agent-base "6" debug "4" @@ -11820,7 +12148,7 @@ is-root@2.1.0: resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== -is-shared-array-buffer@^1.0.1: +is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== @@ -11964,7 +12292,7 @@ isomorphic-ws@4.0.1: resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== -isstream@0.1.x, isstream@~0.1.2: +isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= @@ -12002,7 +12330,7 @@ istanbul-lib-instrument@^4.0.3: istanbul-lib-coverage "^3.0.0" semver "^6.3.0" -istanbul-lib-instrument@^5.0.4: +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== @@ -12058,7 +12386,7 @@ istanbul-reports@^2.2.6: dependencies: html-escaper "^2.0.0" -istanbul-reports@^3.0.2: +istanbul-reports@^3.0.2, istanbul-reports@^3.1.3: version "3.1.4" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== @@ -12181,6 +12509,40 @@ jest-changed-files@^26.6.2: execa "^4.0.0" throat "^5.0.0" +jest-changed-files@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" + integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== + dependencies: + "@jest/types" "^27.5.1" + execa "^5.0.0" + throat "^6.0.1" + +jest-circus@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" + integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + jest-cli@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-24.9.0.tgz#ad2de62d07472d419c6abc301fc432b98b10d2af" @@ -12219,6 +12581,24 @@ jest-cli@^26.2.2, jest-cli@^26.6.3: prompts "^2.0.1" yargs "^15.4.1" +jest-cli@^27.4.2: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" + integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== + dependencies: + "@jest/core" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + prompts "^2.0.1" + yargs "^16.2.0" + jest-config@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-24.9.0.tgz#fb1bbc60c73a46af03590719efa4825e6e4dd1b5" @@ -12266,6 +12646,36 @@ jest-config@^26.6.3: micromatch "^4.0.2" pretty-format "^26.6.2" +jest-config@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" + integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== + dependencies: + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.5.1" + "@jest/types" "^27.5.1" + babel-jest "^27.5.1" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.9" + jest-circus "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-get-type "^27.5.1" + jest-jasmine2 "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runner "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^27.5.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" + jest-diff@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" @@ -12296,6 +12706,16 @@ jest-diff@^26.6.2: jest-get-type "^26.3.0" pretty-format "^26.6.2" +jest-diff@^27.0.0, jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + jest-docblock@^24.3.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-24.9.0.tgz#7970201802ba560e1c4092cc25cbedf5af5a8ce2" @@ -12310,6 +12730,13 @@ jest-docblock@^26.0.0: dependencies: detect-newline "^3.0.0" +jest-docblock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" + integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== + dependencies: + detect-newline "^3.0.0" + jest-each@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-24.9.0.tgz#eb2da602e2a610898dbc5f1f6df3ba86b55f8b05" @@ -12332,6 +12759,17 @@ jest-each@^26.6.2: jest-util "^26.6.2" pretty-format "^26.6.2" +jest-each@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" + integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + jest-get-type "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + jest-environment-jsdom-fourteen@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-1.0.1.tgz#4cd0042f58b4ab666950d96532ecb2fc188f96fb" @@ -12369,6 +12807,19 @@ jest-environment-jsdom@^26.0.1, jest-environment-jsdom@^26.6.2: jest-util "^26.6.2" jsdom "^16.4.0" +jest-environment-jsdom@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" + integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jsdom "^16.6.0" + jest-environment-node@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-24.9.0.tgz#333d2d2796f9687f2aeebf0742b519f33c1cbfd3" @@ -12392,6 +12843,18 @@ jest-environment-node@^26.6.2: jest-mock "^26.6.2" jest-util "^26.6.2" +jest-environment-node@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" + integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jest-get-type@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" @@ -12407,6 +12870,11 @@ jest-get-type@^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-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== + jest-haste-map@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" @@ -12447,6 +12915,26 @@ jest-haste-map@^26.6.2: optionalDependencies: fsevents "^2.1.2" +jest-haste-map@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== + dependencies: + "@jest/types" "^27.5.1" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^27.5.1" + jest-serializer "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + jest-jasmine2@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz#1f7b1bd3242c1774e62acabb3646d96afc3be6a0" @@ -12493,6 +12981,29 @@ jest-jasmine2@^26.6.3: pretty-format "^26.6.2" throat "^5.0.0" +jest-jasmine2@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" + integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + throat "^6.0.1" + jest-leak-detector@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz#b665dea7c77100c5c4f7dfcb153b65cf07dcf96a" @@ -12509,6 +13020,14 @@ jest-leak-detector@^26.6.2: jest-get-type "^26.3.0" pretty-format "^26.6.2" +jest-leak-detector@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" + integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== + dependencies: + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + jest-matcher-utils@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" @@ -12529,6 +13048,16 @@ jest-matcher-utils@^26.6.2: jest-get-type "^26.3.0" pretty-format "^26.6.2" +jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== + dependencies: + chalk "^4.0.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + jest-message-util@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" @@ -12558,6 +13087,21 @@ jest-message-util@^26.6.2: slash "^3.0.0" stack-utils "^2.0.2" +jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.5.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^24.0.0, jest-mock@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" @@ -12573,6 +13117,14 @@ jest-mock@^26.6.2: "@jest/types" "^26.6.2" "@types/node" "*" +jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-pnp-resolver@^1.2.1, jest-pnp-resolver@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" @@ -12588,6 +13140,11 @@ jest-regex-util@^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== +jest-regex-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== + jest-resolve-dependencies@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz#ad055198959c4cfba8a4f066c673a3f0786507ab" @@ -12606,6 +13163,15 @@ jest-resolve-dependencies@^26.6.3: jest-regex-util "^26.0.0" jest-snapshot "^26.6.2" +jest-resolve-dependencies@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" + integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== + dependencies: + "@jest/types" "^27.5.1" + jest-regex-util "^27.5.1" + jest-snapshot "^27.5.1" + jest-resolve@24.9.0, jest-resolve@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-24.9.0.tgz#dff04c7687af34c4dd7e524892d9cf77e5d17321" @@ -12631,6 +13197,22 @@ jest-resolve@^26.6.2: resolve "^1.18.1" slash "^3.0.0" +jest-resolve@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" + integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + jest-runner@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-24.9.0.tgz#574fafdbd54455c2b34b4bdf4365a23857fcdf42" @@ -12682,6 +13264,33 @@ jest-runner@^26.6.3: source-map-support "^0.5.6" throat "^5.0.0" +jest-runner@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" + integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + graceful-fs "^4.2.9" + jest-docblock "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-haste-map "^27.5.1" + jest-leak-detector "^27.5.1" + jest-message-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runtime "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + source-map-support "^0.5.6" + throat "^6.0.1" + jest-runtime@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-24.9.0.tgz#9f14583af6a4f7314a6a9d9f0226e1a781c8e4ac" @@ -12744,6 +13353,34 @@ jest-runtime@^26.6.3: strip-bom "^4.0.0" yargs "^15.4.1" +jest-runtime@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" + integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/globals" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + strip-bom "^4.0.0" + jest-serializer@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" @@ -12757,6 +13394,14 @@ jest-serializer@^26.6.2: "@types/node" "*" graceful-fs "^4.2.4" +jest-serializer@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.9" + jest-snapshot@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-24.9.0.tgz#ec8e9ca4f2ec0c5c87ae8f925cf97497b0e951ba" @@ -12798,6 +13443,34 @@ jest-snapshot@^26.6.2: pretty-format "^26.6.2" semver "^7.3.2" +jest-snapshot@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" + integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.5.1" + graceful-fs "^4.2.9" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + jest-haste-map "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + natural-compare "^1.4.0" + pretty-format "^27.5.1" + semver "^7.3.2" + jest-util@26.x, jest-util@^26.1.0, jest-util@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" @@ -12828,6 +13501,18 @@ jest-util@^24.0.0, jest-util@^24.9.0: slash "^2.0.0" source-map "^0.6.0" +jest-util@^27.0.0, jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-validate@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" @@ -12852,6 +13537,18 @@ jest-validate@^26.6.2: leven "^3.1.0" pretty-format "^26.6.2" +jest-validate@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" + integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== + dependencies: + "@jest/types" "^27.5.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.5.1" + leven "^3.1.0" + pretty-format "^27.5.1" + jest-watch-typeahead@0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz#e5be959698a7fa2302229a5082c488c3c8780a4a" @@ -12891,6 +13588,19 @@ jest-watcher@^26.6.2: jest-util "^26.6.2" string-length "^4.0.1" +jest-watcher@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" + integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== + dependencies: + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.5.1" + string-length "^4.0.1" + jest-worker@^24.6.0, jest-worker@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" @@ -12916,6 +13626,15 @@ jest-worker@^26.6.2: merge-stream "^2.0.0" supports-color "^7.0.0" +jest-worker@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + jest@24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest/-/jest-24.9.0.tgz#987d290c05a08b52c56188c1002e368edb007171" @@ -12942,6 +13661,15 @@ jest@26.6.3: import-local "^3.0.2" jest-cli "^26.6.3" +jest@27.4.2: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.4.2.tgz#4fb1211ad0b9955ef09a11b96684180a90638985" + integrity sha512-TAReynFYCfHNcrL+8Z74WPGafLFLF++bGkrpcsk6cO5G9S2VuJGhu2c44YFForMgF0GlYmtbpmeznkvZpNgTxg== + dependencies: + "@jest/core" "^27.4.2" + import-local "^3.0.2" + jest-cli "^27.4.2" + js-levenshtein@^1.1.3: version "1.1.6" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" @@ -13059,7 +13787,7 @@ jsdom@^14.1.0: ws "^6.1.2" xml-name-validator "^3.0.0" -jsdom@^16.4.0: +jsdom@^16.4.0, jsdom@^16.6.0: version "16.7.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== @@ -13803,11 +14531,6 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.4.0: - version "7.8.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.8.0.tgz#649aaeb294a56297b5cbc5d70f198dcc5ebe5747" - integrity sha512-AmXqneQZL3KZMIgBpaPTeI6pfwh+xQ2vutMsyqOu1TBdEXFZgpG/80wuJ531w2ZN7TI0/oc8CPxzh/DKQudZqg== - lru-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" @@ -14621,9 +15344,9 @@ nano-json-stream-parser@^0.1.2: integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18= nanoid@^3.1.12, nanoid@^3.1.3: - version "3.3.2" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.2.tgz#c89622fafb4381cd221421c69ec58547a1eec557" - integrity sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA== + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== nanomatch@^1.2.9: version "1.2.13" @@ -14847,9 +15570,9 @@ node-releases@^1.1.52: integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ== node-releases@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" - integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" + integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== noms@0.0.0: version "0.0.0" @@ -15122,7 +15845,7 @@ object-is@^1.0.1: call-bind "^1.0.2" define-properties "^1.1.3" -object-keys@^1.0.12, object-keys@^1.1.1: +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== @@ -15661,7 +16384,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.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== @@ -15835,7 +16558,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -15872,7 +16595,7 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= -pirates@^4.0.1: +pirates@^4.0.1, pirates@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== @@ -16673,6 +17396,15 @@ pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" +pretty-format@^27.0.0, pretty-format@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + private@^0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -16723,17 +17455,6 @@ promise@^8.0.3: dependencies: asap "~2.0.6" -prompt@1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/prompt/-/prompt-1.2.2.tgz#b624fcf53aa6c8c5637e009c193ef69eee45dbe0" - integrity sha512-XNXhNv3PUHJDcDkISpCwSJxtw9Bor4FZnlMUDW64N/KCPdxhfVlpD5+YUXI/Z8a9QWmOhs9KSiVtR8nzPS0BYA== - dependencies: - "@colors/colors" "1.5.0" - async "~0.9.0" - read "1.0.x" - revalidator "0.1.x" - winston "2.x" - prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -17106,9 +17827,9 @@ react-error-boundary@^3.1.0: "@babel/runtime" "^7.12.5" react-error-overlay@^6.0.7: - version "6.0.10" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.10.tgz#0fe26db4fa85d9dbb8624729580e90e7159a59a6" - integrity sha512-mKR90fX7Pm5seCOfz8q9F+66VCc1PGsWSBxKbITjfKVQHMNF2zudxHnMdJiB1fRCb+XsbQV9sO9DCkgsMQgBIA== + version "6.0.11" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" + integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== react-is@^16.12.0, react-is@^16.13.1, react-is@^16.8.4: version "16.13.1" @@ -17334,7 +18055,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -read@1, read@1.0.x, read@~1.0.1: +read@1, read@~1.0.1: version "1.0.7" resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= @@ -17517,12 +18238,13 @@ regex-parser@2.2.11: integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" - integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" + functions-have-names "^1.2.2" regexpp@^2.0.1: version "2.0.1" @@ -17737,6 +18459,11 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" @@ -17793,11 +18520,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -revalidator@0.1.x: - version "0.1.8" - resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b" - integrity sha1-/s5hv6DBtSoga9axgZgYS91SOjs= - rework-visit@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a" @@ -18054,11 +18776,11 @@ semver@7.3.5: lru-cache "^6.0.0" semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: - version "7.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.6.tgz#5d73886fb9c0c6602e79440b97165c29581cbb2b" - integrity sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w== + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: - lru-cache "^7.4.0" + lru-cache "^6.0.0" send@0.17.1: version "0.17.1" @@ -18405,15 +19127,15 @@ socks-proxy-agent@^5.0.0: socks "^2.3.3" socks-proxy-agent@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz#e664e8f1aaf4e1fb3df945f09e3d94f911137f87" - integrity sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew== + version "6.2.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz#f6b5229cc0cbd6f2f202d9695f09d871e951c85e" + integrity sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ== dependencies: agent-base "^6.0.2" - debug "^4.3.1" - socks "^2.6.1" + debug "^4.3.3" + socks "^2.6.2" -socks@^2.3.3, socks@^2.6.1: +socks@^2.3.3, socks@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.2.tgz#ec042d7960073d40d94268ff3bb727dc685f111a" integrity sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA== @@ -18647,11 +19369,6 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== -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@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.5.tgz#a19b0b01947e0029c8e451d5d61a498f5bb1471b" @@ -18659,7 +19376,7 @@ stack-utils@^1.0.1: dependencies: escape-string-regexp "^2.0.0" -stack-utils@^2.0.2: +stack-utils@^2.0.2, stack-utils@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== @@ -19036,6 +19753,13 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^8.0.0: + 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-hyperlinks@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" @@ -19294,6 +20018,11 @@ throat@^5.0.0: resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== +throat@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== + through2@^2.0.0, through2@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -19506,6 +20235,20 @@ ts-jest@26.5.4: semver "7.x" yargs-parser "20.x" +ts-jest@27.0.7: + version "27.0.7" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.0.7.tgz#fb7c8c8cb5526ab371bc1b23d06e745652cca2d0" + integrity sha512-O41shibMqzdafpuP+CkrOL7ykbmLh+FqQrXEmV9CydQ5JBk0Sj0uAEF5TNNe94fZWKm3yYvWa/IbyV4Yg1zK2Q== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^27.0.0" + json5 "2.x" + lodash.memoize "4.x" + make-error "1.x" + semver "7.x" + yargs-parser "20.x" + ts-loader@8.0.17: version "8.0.17" resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.0.17.tgz#98f2ccff9130074f4079fd89b946b4c637b1f2fc" @@ -19531,6 +20274,24 @@ ts-morph@10.0.1: "@ts-morph/common" "~0.8.0" code-block-writer "^10.1.1" +ts-node@10.4.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7" + integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A== + dependencies: + "@cspotcode/source-map-support" "0.7.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + yn "3.1.1" + ts-node@10.7.0: version "10.7.0" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" @@ -19726,6 +20487,11 @@ typescript@4.0.7: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.7.tgz#7168032c43d2a2671c95c07812f69523c79590af" integrity sha512-yi7M4y74SWvYbnazbn8/bmJmX4Zlej39ZOqwG/8dut/MYoSQ119GY9ZFbbGsD4PFZYWxqik/XsP3vk3+W5H3og== +typescript@4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324" + integrity sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA== + typescript@^4.0: version "4.6.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" @@ -19742,9 +20508,9 @@ uglify-js@^2.8.29: uglify-to-browserify "~1.0.0" uglify-js@^3.1.4: - version "3.15.3" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.3.tgz#9aa82ca22419ba4c0137642ba0df800cb06e0471" - integrity sha512-6iCVm2omGJbsu3JWac+p6kUiOpg3wFO2f8lIXjfEb8RrmLjzog1wTPMmwKB7swfzzqxj9YM+sGUM++u1qN4qJg== + version "3.15.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.4.tgz#fa95c257e88f85614915b906204b9623d4fa340d" + integrity sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA== uglify-to-browserify@~1.0.0: version "1.0.2" @@ -20105,9 +20871,9 @@ uuid@^3.0.1, uuid@^3.3.2: integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== v8-compile-cache-lib@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8" - integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== v8-compile-cache@^2.0.3: version "2.3.0" @@ -20123,6 +20889,15 @@ v8-to-istanbul@^7.0.0: convert-source-map "^1.6.0" source-map "^0.7.3" +v8-to-istanbul@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" + integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + valid-url@1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" @@ -20844,18 +21619,6 @@ window-size@^0.2.0: resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= -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, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" From 1e2eb90af053f3f7290da4c91c36a16c9fa2f774 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 18 Apr 2022 13:46:11 -0700 Subject: [PATCH 19/41] fix test --- packages/js/core/src/__tests__/resolveUri.spec.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/js/core/src/__tests__/resolveUri.spec.ts b/packages/js/core/src/__tests__/resolveUri.spec.ts index b5cf23daf6..048f47a146 100644 --- a/packages/js/core/src/__tests__/resolveUri.spec.ts +++ b/packages/js/core/src/__tests__/resolveUri.spec.ts @@ -93,7 +93,7 @@ describe("resolveUri", () => { options: GetManifestOptions ) => { const manifest = { - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", language: "", modules: {}, __type: "Web3ApiManifest", @@ -125,7 +125,7 @@ describe("resolveUri", () => { client: Client ) => { const manifest = { - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", language: "", modules: {}, __type: "Web3ApiManifest", @@ -154,7 +154,7 @@ describe("resolveUri", () => { client: Client ) => { const manifest = { - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", language: "", modules: {}, __type: "Web3ApiManifest", @@ -285,7 +285,7 @@ describe("resolveUri", () => { expect(apiIdentity).toMatchObject({ uri: new Uri("ipfs/QmHash"), manifest: { - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", }, uriResolver: "w3://ens/ipfs", }); @@ -309,7 +309,7 @@ describe("resolveUri", () => { expect(apiIdentity).toMatchObject({ uri: new Uri("my/something-different"), manifest: { - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", }, uriResolver: "w3://ens/my-plugin", }); @@ -333,7 +333,7 @@ describe("resolveUri", () => { expect(apiIdentity).toMatchObject({ uri: new Uri("ipfs/QmHash"), manifest: { - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", dog: "cat", }, uriResolver: "w3://ens/ipfs", @@ -358,7 +358,7 @@ describe("resolveUri", () => { expect(apiIdentity).toMatchObject({ uri: new Uri("my/something-different"), manifest: { - format: "0.0.1-prealpha.7", + format: "0.0.1-prealpha.8", }, uriResolver: "w3://ens/my-plugin", }); From 09d65b450eeade42b9b5e99166532f4f8d7af2a7 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 18 Apr 2022 14:57:53 -0700 Subject: [PATCH 20/41] test-env wrapper deploy changes init --- packages/cli/src/__tests__/e2e/deploy.spec.ts | 4 +- packages/cli/src/commands/deploy.ts | 2 +- .../ethereum/src/__tests__/e2e.spec.ts | 4 +- .../src/__tests__/integration/package.json | 3 +- .../src/__tests__/integration/web3api.yaml | 3 +- packages/js/test-env/src/index.ts | 50 +++++++++++-------- 6 files changed, 39 insertions(+), 27 deletions(-) diff --git a/packages/cli/src/__tests__/e2e/deploy.spec.ts b/packages/cli/src/__tests__/e2e/deploy.spec.ts index 52136e92b3..a1a441b1e8 100644 --- a/packages/cli/src/__tests__/e2e/deploy.spec.ts +++ b/packages/cli/src/__tests__/e2e/deploy.spec.ts @@ -34,6 +34,7 @@ const setup = async (domainNames: string[]) => { const registrarAddress = data.registrarAddress const signer = new Wallet("0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"); + // TODO: use the "loadDeployManifest" function const deployManifest = yaml.load( await fs.promises.readFile( `${projectRoot}/web3api.deploy.yaml`, @@ -69,6 +70,7 @@ const setup = async (domainNames: string[]) => { ], }); + // TODO: why not use the ENS wrapper here? for await (const domainName of domainNames) { const label = "0x" + keccak256(domainName) await client.query({ @@ -89,7 +91,7 @@ const setup = async (domainNames: string[]) => { } `, }); - + await client.query({ uri: "w3://ens/ethereum.web3api.eth", query: ` diff --git a/packages/cli/src/commands/deploy.ts b/packages/cli/src/commands/deploy.ts index 2aab2a9ee5..1231a800fd 100644 --- a/packages/cli/src/commands/deploy.ts +++ b/packages/cli/src/commands/deploy.ts @@ -82,7 +82,7 @@ export default { const deployManifest = await project.getDeployManifest(); if (!deployManifest) { - throw new Error("No deploy manifest"); + throw new Error("No deploy manifest found."); } const packageNames = [ diff --git a/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts b/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts index fa712f6bad..baab0d4c1a 100644 --- a/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts +++ b/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts @@ -90,8 +90,8 @@ describe("Ethereum Plugin", () => { await stopTestEnvironment(); }); - describe("Query", () => { - it("callContractView", async () => { + describe.only("Query", () => { + it.only("callContractView", async () => { const node = namehash("whatever.eth") const response = await client.query<{ callContractView: string }>({ uri, diff --git a/packages/js/plugins/ethereum/src/__tests__/integration/package.json b/packages/js/plugins/ethereum/src/__tests__/integration/package.json index f7312b38ee..c996a2a13a 100644 --- a/packages/js/plugins/ethereum/src/__tests__/integration/package.json +++ b/packages/js/plugins/ethereum/src/__tests__/integration/package.json @@ -8,8 +8,7 @@ "build:web3api": "npx w3 build", "test:env:up": "npx w3 test-env up", "test:env:down": "npx w3 test-env down", - "deploy": "yarn deploy:web3api", - "deploy:web3api": "npx w3 build --ipfs http://localhost:5001 --test-ens simplestorage.eth" + "deploy": "npx w3 deploy" }, "dependencies": { "@web3api/wasm-as": "0.0.1-prealpha.71" diff --git a/packages/js/plugins/ethereum/src/__tests__/integration/web3api.yaml b/packages/js/plugins/ethereum/src/__tests__/integration/web3api.yaml index 630932aff7..b5a74af969 100644 --- a/packages/js/plugins/ethereum/src/__tests__/integration/web3api.yaml +++ b/packages/js/plugins/ethereum/src/__tests__/integration/web3api.yaml @@ -1,4 +1,5 @@ -format: 0.0.1-prealpha.5 +format: 0.0.1-prealpha.8 +name: EthereumIntegration build: ./web3api.build.yaml language: wasm/assemblyscript modules: diff --git a/packages/js/test-env/src/index.ts b/packages/js/test-env/src/index.ts index 40797b14e9..20257b6b09 100644 --- a/packages/js/test-env/src/index.ts +++ b/packages/js/test-env/src/index.ts @@ -137,30 +137,40 @@ export async function buildAndDeployApi( // create a new ENS domain const apiEns = `${generateName()}.eth`; - // build & deploy the protocol - const { exitCode, stdout, stderr } = await runCLI({ - args: [ - "build", - "--manifest-file", - `${apiAbsPath}/web3api.yaml`, - "--output-dir", - `${apiAbsPath}/build`, - "--ipfs", - ipfsProvider, - "--test-ens", - `${ensAddress},${apiEns}`, - ], - }); + // build API + { + const { exitCode, stdout, stderr } = await runCLI({ + args: [ + "build", + "--manifest-file", + `${apiAbsPath}/web3api.yaml`, + "--output-dir", + `${apiAbsPath}/build`, + ], + }); - if (exitCode !== 0) { - console.error(`w3 exited with code: ${exitCode}`); - console.log(`stderr:\n${stderr}`); - console.log(`stdout:\n${stdout}`); - throw Error("w3 CLI failed"); + if (exitCode !== 0) { + console.error(`w3 exited with code: ${exitCode}`); + console.log(`stderr:\n${stderr}`); + console.log(`stdout:\n${stdout}`); + throw Error("w3 CLI failed"); + } } + // register ENS domain + + + // manually configure manifests + + // deploy API + { + + } + + // remove manually configured manifests + // get the IPFS CID of the published package - const extractCID = /IPFS { (([A-Z]|[a-z]|[0-9])*) }/; + const extractCID = /(w3:\/\/ipfs\/[A-Za-z0-9]+)/; const result = stdout.match(extractCID); if (!result) { From 65a8f36c6c3b1abef90317ef85edcc0e6a4bf486 Mon Sep 17 00:00:00 2001 From: namesty Date: Tue, 19 Apr 2022 04:42:28 +0200 Subject: [PATCH 21/41] (fix): fixed filesystem URIs for IPFS deployer and load manifest todo --- packages/cli/src/__tests__/e2e/deploy.spec.ts | 10 +++------- .../__tests__/project/web3api.deploy.fail-between.yaml | 2 +- .../project/web3api.deploy.invalid-config.yaml | 2 +- .../src/__tests__/project/web3api.deploy.no-ext.yaml | 2 +- packages/cli/src/__tests__/project/web3api.deploy.yaml | 2 +- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/cli/src/__tests__/e2e/deploy.spec.ts b/packages/cli/src/__tests__/e2e/deploy.spec.ts index a1a441b1e8..755fbc335c 100644 --- a/packages/cli/src/__tests__/e2e/deploy.spec.ts +++ b/packages/cli/src/__tests__/e2e/deploy.spec.ts @@ -6,13 +6,14 @@ import { } from "@web3api/test-env-js"; import path from "path"; import axios from "axios"; -import { DeployManifest, Web3ApiClient } from "@web3api/client-js"; +import { Web3ApiClient } from "@web3api/client-js"; import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; import { keccak256 } from "js-sha3"; import { Wallet } from "ethers"; import { namehash } from "ethers/lib/utils"; import yaml from "js-yaml"; import fs from "fs"; +import { loadDeployManifest } from "../../lib"; const projectRoot = path.resolve(__dirname, "../project/"); @@ -35,12 +36,7 @@ const setup = async (domainNames: string[]) => { const signer = new Wallet("0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"); // TODO: use the "loadDeployManifest" function - const deployManifest = yaml.load( - await fs.promises.readFile( - `${projectRoot}/web3api.deploy.yaml`, - "utf8" - ) - ) as DeployManifest; + const deployManifest = await loadDeployManifest(`${projectRoot}/web3api.deploy.yaml`); Object.entries(deployManifest.stages).forEach(([key, value]) => { if (value.config && value.config.ensRegistryAddress) { diff --git a/packages/cli/src/__tests__/project/web3api.deploy.fail-between.yaml b/packages/cli/src/__tests__/project/web3api.deploy.fail-between.yaml index 6f3c346d18..a424c340bc 100644 --- a/packages/cli/src/__tests__/project/web3api.deploy.fail-between.yaml +++ b/packages/cli/src/__tests__/project/web3api.deploy.fail-between.yaml @@ -2,7 +2,7 @@ format: 0.0.1-prealpha.1 stages: ipfs_deploy: package: ipfs - uri: file/./build + uri: fs/./build from_deploy: package: ens depends_on: ipfs_deploy diff --git a/packages/cli/src/__tests__/project/web3api.deploy.invalid-config.yaml b/packages/cli/src/__tests__/project/web3api.deploy.invalid-config.yaml index 37b81baaca..6586dc8bb7 100644 --- a/packages/cli/src/__tests__/project/web3api.deploy.invalid-config.yaml +++ b/packages/cli/src/__tests__/project/web3api.deploy.invalid-config.yaml @@ -2,7 +2,7 @@ format: 0.0.1-prealpha.1 stages: ipfs_deploy: package: ipfs - uri: file/./build + uri: fs/./build from_deploy: package: ens depends_on: ipfs_deploy diff --git a/packages/cli/src/__tests__/project/web3api.deploy.no-ext.yaml b/packages/cli/src/__tests__/project/web3api.deploy.no-ext.yaml index 5d31532e0f..11b28ba091 100644 --- a/packages/cli/src/__tests__/project/web3api.deploy.no-ext.yaml +++ b/packages/cli/src/__tests__/project/web3api.deploy.no-ext.yaml @@ -2,6 +2,6 @@ format: 0.0.1-prealpha.1 stages: ipfs_test: package: ipfs-test - uri: file/./build + uri: fs/./build config: foo: bar \ No newline at end of file diff --git a/packages/cli/src/__tests__/project/web3api.deploy.yaml b/packages/cli/src/__tests__/project/web3api.deploy.yaml index 283fabcd22..e1da00e826 100644 --- a/packages/cli/src/__tests__/project/web3api.deploy.yaml +++ b/packages/cli/src/__tests__/project/web3api.deploy.yaml @@ -2,7 +2,7 @@ format: 0.0.1-prealpha.1 stages: ipfs_deploy: package: ipfs - uri: file/./build + uri: fs/./build from_deploy: package: ens depends_on: ipfs_deploy From 7502f779f2da1960ab92866efed4e5ff14efe209 Mon Sep 17 00:00:00 2001 From: namesty Date: Tue, 19 Apr 2022 04:43:47 +0200 Subject: [PATCH 22/41] (wip): updated buildAndDeploy test method to use deploy command --- packages/cli/src/lib/deployers/ens/index.ts | 2 +- packages/cli/src/lib/deployers/ipfs/index.ts | 2 +- packages/js/test-env/package.json | 5 +- packages/js/test-env/src/index.ts | 182 ++++++++++++++++--- packages/test-env/dev-server/src/index.js | 21 --- yarn.lock | 46 ++--- 6 files changed, 187 insertions(+), 71 deletions(-) diff --git a/packages/cli/src/lib/deployers/ens/index.ts b/packages/cli/src/lib/deployers/ens/index.ts index 23c60c5b65..74114efd2b 100644 --- a/packages/cli/src/lib/deployers/ens/index.ts +++ b/packages/cli/src/lib/deployers/ens/index.ts @@ -68,7 +68,7 @@ class ENSPublisher implements Deployer { await tx.wait(); - return new Uri(`ens/${config.domainName}`); + return new Uri(`w3://ens/${config.domainName}`); } } diff --git a/packages/cli/src/lib/deployers/ipfs/index.ts b/packages/cli/src/lib/deployers/ipfs/index.ts index fce0b36ffb..eb61efa66c 100644 --- a/packages/cli/src/lib/deployers/ipfs/index.ts +++ b/packages/cli/src/lib/deployers/ipfs/index.ts @@ -71,7 +71,7 @@ class IPFSDeployer implements Deployer { throw new Error("Could not find root folder's CID"); } - return new Uri(`ipfs/${directoryCID}`); + return new Uri(`w3://ipfs/${directoryCID}`); } else { throw new Error("Unexpected error: " + resp.status); } diff --git a/packages/js/test-env/package.json b/packages/js/test-env/package.json index 690734fe89..76e062cff6 100644 --- a/packages/js/test-env/package.json +++ b/packages/js/test-env/package.json @@ -17,7 +17,10 @@ }, "dependencies": { "axios": "0.21.2", - "spawn-command": "0.0.2-1" + "spawn-command": "0.0.2-1", + "@web3api/core-js": "0.0.1-prealpha.71", + "ethers": "5.6.4", + "js-yaml": "4.1.0" }, "devDependencies": { "rimraf": "3.0.2", diff --git a/packages/js/test-env/src/index.ts b/packages/js/test-env/src/index.ts index 20257b6b09..2960a8d25c 100644 --- a/packages/js/test-env/src/index.ts +++ b/packages/js/test-env/src/index.ts @@ -2,6 +2,9 @@ import path from "path"; import spawn from "spawn-command"; import axios from "axios"; import fs from "fs"; +import ethers from "ethers"; +import yaml from "js-yaml"; +import { Client, deserializeWeb3ApiManifest } from "@web3api/core-js"; interface TestEnvironment { ipfs: string; @@ -126,55 +129,184 @@ export const runCLI = async (options: { }; }; -export async function buildAndDeployApi( - apiAbsPath: string, - ipfsProvider: string, - ensAddress: string -): Promise<{ +export async function buildAndDeployApi({ + apiAbsPath, + ipfsProvider, + ensRegistryAddress, + ensRegistrarAddress, + ensResolverAddress, + ethereumProvider, + client, +}: { + apiAbsPath: string; + ipfsProvider: string; + ensRegistryAddress: string; + ensRegistrarAddress: string; + ensResolverAddress: string; + ethereumProvider: string; + client: Client; +}): Promise<{ ensDomain: string; ipfsCid: string; }> { + const manifestPath = `${apiAbsPath}/web3api.yaml`; + const tempManifestFilename = `web3api-temp.yaml`; + const tempDeployManifestFilename = `web3api.deploy-temp.yaml`; + const tempManifestPath = path.join(apiAbsPath, tempManifestFilename); + const tempDeployManifestPath = path.join( + apiAbsPath, + tempDeployManifestFilename + ); + // create a new ENS domain const apiEns = `${generateName()}.eth`; // build API - { - const { exitCode, stdout, stderr } = await runCLI({ - args: [ - "build", - "--manifest-file", - `${apiAbsPath}/web3api.yaml`, - "--output-dir", - `${apiAbsPath}/build`, - ], - }); + const { + exitCode: buildExitCode, + stdout: buildStdout, + stderr: buildStderr, + } = await runCLI({ + args: [ + "build", + "--manifest-file", + manifestPath, + "--output-dir", + `${apiAbsPath}/build`, + ], + }); - if (exitCode !== 0) { - console.error(`w3 exited with code: ${exitCode}`); - console.log(`stderr:\n${stderr}`); - console.log(`stdout:\n${stdout}`); - throw Error("w3 CLI failed"); - } + if (buildExitCode !== 0) { + console.error(`w3 exited with code: ${buildExitCode}`); + console.log(`stderr:\n${buildStderr}`); + console.log(`stdout:\n${buildStdout}`); + throw Error("w3 CLI failed"); } // register ENS domain - + const ethersProvider = new ethers.providers.JsonRpcProvider(ethereumProvider); + const owner = await ethersProvider.getSigner(0).getAddress(); + + // TODO: deploy ENS wrapper to testenv + const { error: registerError } = await client.invoke({ + uri: ensUri, + module: "mutation", + method: "registerDomain", + input: { + domain: apiEns, + owner, + registrarAddress: ensRegistrarAddress, + registryAddress: ensRegistryAddress, + connection: { + networkNameOrChainId: "testnet", + }, + }, + }); + + if (registerError) { + throw new Error( + `Error publishing API to ENS. Path: ${apiAbsPath}. Error: ${registerError}` + ); + } + + const { error: setResolverError } = await client.invoke({ + uri: ensUri, + module: "mutation", + method: "setResolver", + input: { + domain: apiEns, + resolverAddress: ensResolverAddress, + registryAddress: ensRegistryAddress, + connection: { + networkNameOrChainId: "testnet", + }, + }, + }); + + if (setResolverError) { + throw new Error( + `Error publishing API to ENS. Path: ${apiAbsPath}. Error: ${setResolverError}` + ); + } // manually configure manifests + const web3apiManifest = deserializeWeb3ApiManifest( + fs.readFileSync(path.join(apiAbsPath, "web3api.yaml"), "utf-8") + ); + + const useTempManifests = !web3apiManifest.deploy; + + if (useTempManifests) { + fs.writeFileSync( + tempManifestPath, + yaml.safeDump({ + ...web3apiManifest, + deploy: `./${tempManifestFilename}`, + }) + ); + + fs.writeFileSync( + tempDeployManifestPath, + yaml.safeDump({ + format: "0.0.1-prealpha.1", + stages: { + ipfsDeploy: { + package: "ipfs", + uri: "fs/./build", + config: { + gatewayUri: ipfsProvider, + }, + }, + ensPublish: { + package: "ens", + // eslint-disable-next-line @typescript-eslint/naming-convention + depends_on: "ipfsDeploy", + config: { + domainName: apiEns, + provider: ethereumProvider, + ensRegistryAddress, + }, + }, + }, + }) + ); + } + // deploy API - { + const { + exitCode: deployExitCode, + stdout: deployStdout, + stderr: deployStderr, + } = await runCLI({ + args: [ + "deploy", + "--manifest-file", + useTempManifests ? tempManifestPath : manifestPath, + ], + }); + + if (deployExitCode !== 0) { + console.error(`w3 exited with code: ${deployExitCode}`); + console.log(`stderr:\n${deployStderr}`); + console.log(`stdout:\n${deployStdout}`); + throw Error("w3 CLI failed"); } // remove manually configured manifests + if (useTempManifests) { + fs.unlinkSync(tempManifestPath); + fs.unlinkSync(tempDeployManifestPath); + } + // get the IPFS CID of the published package const extractCID = /(w3:\/\/ipfs\/[A-Za-z0-9]+)/; - const result = stdout.match(extractCID); + const result = deployStdout.match(extractCID); if (!result) { - throw Error(`W3 CLI output missing IPFS CID.\nOutput: ${stdout}`); + throw Error(`W3 CLI output missing IPFS CID.\nOutput: ${deployStdout}`); } const apiCid = result[1]; diff --git a/packages/test-env/dev-server/src/index.js b/packages/test-env/dev-server/src/index.js index bf1d36ffba..0eac9e58ea 100644 --- a/packages/test-env/dev-server/src/index.js +++ b/packages/test-env/dev-server/src/index.js @@ -56,27 +56,6 @@ router.get('/deploy-ens', async (req, res) => { res.send(addresses); }); -router.get('/register-ens', async (req, res) => { - if (addresses.ensAddress === undefined) { - throw Error("ENS hasn't been deployed, call /deploy-ens"); - } - - const web3 = getWeb3(); - const accounts = await web3.eth.getAccounts(); - - await registerENS({ - web3, - accounts, - addresses, - domain: req.query.domain, - cid: req.query.cid - }); - - res.send({ - success: true - }); -}); - router.get('/status', (req, res) => { res.send({ running: true diff --git a/yarn.lock b/yarn.lock index d31d117f84..ed398b3fe7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1556,10 +1556,10 @@ nano-base32 "^1.0.1" ripemd160 "^2.0.2" -"@ensdomains/ens@0.4.4": - version "0.4.4" - resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.4.tgz#05e7bb138471a5e5844b4c1f263ec0ad7edcd272" - integrity sha512-Qya0A4pd0dd3fF4tPqJve9eyEHp82jIMv17ElZU4dSHy68xN8sEpuiyI6Z8+2sGeHLRQ55LaCM6p293YHnYRlQ== +"@ensdomains/ens@0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.3.tgz#f4a6b55146fe526c9a50e13f373bf90d36ca94dc" + integrity sha512-btC+fGze//ml8SMNCx5DgwM8+kG2t+qDCZrqlL/2+PV4CNxnRIpR3egZ49D9FqS52PFoYLmz6MaQfl7AO3pUMA== dependencies: bluebird "^3.5.2" eth-ens-namehash "^2.0.8" @@ -1569,25 +1569,27 @@ testrpc "0.0.1" web3-utils "^1.0.0-beta.31" -"@ensdomains/ens@0.4.5": - version "0.4.5" - resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" - integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== +"@ensdomains/ens@0.4.4": + version "0.4.4" + resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.4.tgz#05e7bb138471a5e5844b4c1f263ec0ad7edcd272" + integrity sha512-Qya0A4pd0dd3fF4tPqJve9eyEHp82jIMv17ElZU4dSHy68xN8sEpuiyI6Z8+2sGeHLRQ55LaCM6p293YHnYRlQ== dependencies: bluebird "^3.5.2" eth-ens-namehash "^2.0.8" + ethereumjs-testrpc "^6.0.3" + ganache-cli "^6.1.0" solc "^0.4.20" testrpc "0.0.1" web3-utils "^1.0.0-beta.31" -"@ensdomains/ensjs@^2.0.1": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@ensdomains/ensjs/-/ensjs-2.1.0.tgz#0a7296c1f3d735ef019320d863a7846a0760c460" - integrity sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog== +"@ensdomains/ensjs@2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@ensdomains/ensjs/-/ensjs-2.0.1.tgz#c27438f9ca074825ddb08430988c7decf2062a91" + integrity sha512-gZLntzE1xqPNkPvaHdJlV5DXHms8JbHBwrXc2xNrL1AylERK01Lj/txCCZyVQqFd3TvUO1laDbfUv8VII0qrjg== dependencies: "@babel/runtime" "^7.4.4" "@ensdomains/address-encoder" "^0.1.7" - "@ensdomains/ens" "0.4.5" + "@ensdomains/ens" "0.4.3" "@ensdomains/resolver" "0.2.4" content-hash "^2.5.2" eth-ens-namehash "^2.0.8" @@ -9548,7 +9550,7 @@ ethers@5.6.2: "@ethersproject/web" "5.6.0" "@ethersproject/wordlists" "5.6.0" -ethers@^5.0.13: +ethers@5.6.4, ethers@^5.0.13: version "5.6.4" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.6.4.tgz#23629e9a7d4bc5802dfb53d4da420d738744b53c" integrity sha512-62UIfxAQXdf67TeeOaoOoPctm5hUlYgfd0iW3wxfj7qRYKDcvvy0f+sJ3W2/Pyx77R8dblvejA8jokj+lS+ATQ== @@ -10234,7 +10236,7 @@ fork-ts-checker-webpack-plugin@3.1.1: tapable "^1.0.0" worker-rpc "^0.1.0" -form-data@4.0.0, form-data@^4.0.0: +form-data@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== @@ -13703,6 +13705,13 @@ js-yaml@3.14.0: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + 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" @@ -13711,13 +13720,6 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" From e2c318b52d4896bc430d7843c8ce35628ddf679e Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 20 Apr 2022 14:59:23 +0200 Subject: [PATCH 23/41] (chore): changed IPFS deployer impl to use http client package --- packages/cli/src/lib/deployers/ipfs/file.ts | 50 ---------- .../cli/src/lib/deployers/ipfs/formData.ts | 72 -------------- packages/cli/src/lib/deployers/ipfs/index.ts | 74 ++++---------- packages/cli/src/lib/deployers/ipfs/utils.ts | 27 ------ yarn.lock | 96 +++++++++---------- 5 files changed, 68 insertions(+), 251 deletions(-) delete mode 100644 packages/cli/src/lib/deployers/ipfs/file.ts delete mode 100644 packages/cli/src/lib/deployers/ipfs/formData.ts delete mode 100644 packages/cli/src/lib/deployers/ipfs/utils.ts diff --git a/packages/cli/src/lib/deployers/ipfs/file.ts b/packages/cli/src/lib/deployers/ipfs/file.ts deleted file mode 100644 index 3a7f93e086..0000000000 --- a/packages/cli/src/lib/deployers/ipfs/file.ts +++ /dev/null @@ -1,50 +0,0 @@ -import fs from "fs"; -import path from "path"; - -export interface DirectoryBlob { - directories: DirectoryEntry[]; - files: FileEntry[]; -} - -export interface FileEntry { - name: string; - data: string; -} - -export interface DirectoryEntry { - name: string; - directories: DirectoryEntry[]; - files: FileEntry[]; -} - -export const convertFileToEntry = (pathToFile: string): FileEntry => { - const name = path.basename(pathToFile); - const data = fs.readFileSync(pathToFile, { encoding: "utf-8" }); - - return { - name, - data, - }; -}; - -export const convertDirectoryToEntry = (pathToDir: string): DirectoryEntry => { - const name = path.basename(pathToDir); - - const filesAndDirs = fs.readdirSync(pathToDir, { withFileTypes: true }); - - const files = filesAndDirs - .filter((dirent) => !dirent.isDirectory()) - .map((dirent) => convertFileToEntry(path.join(pathToDir, dirent.name))); - - const directories = filesAndDirs - .filter((dirent) => dirent.isDirectory()) - .map((dirent) => - convertDirectoryToEntry(path.join(pathToDir, dirent.name)) - ); - - return { - name, - files, - directories, - }; -}; diff --git a/packages/cli/src/lib/deployers/ipfs/formData.ts b/packages/cli/src/lib/deployers/ipfs/formData.ts deleted file mode 100644 index 44a5e31ae7..0000000000 --- a/packages/cli/src/lib/deployers/ipfs/formData.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { DirectoryBlob, DirectoryEntry, FileEntry } from "./file"; - -interface FormDataEntry { - key: string; - data?: string; - opts?: FormDataOptions; -} - -interface FormDataOptions { - contentType?: string; - fileName?: string; - filePath?: string; -} - -function convertDirectoryEntryToFormData( - dirs: DirectoryEntry[], - path: string -): FormDataEntry[] { - let formData: FormDataEntry[] = []; - for (let i = 0; i < dirs.length; i++) { - const dir = dirs[i]; - formData.push({ - key: dir.name, - opts: { - contentType: "application/x-directory", - fileName: encodeURIComponent(dir.name), - filePath: "", - }, - }); - const newPath = path + dir.name + "/"; - for (let j = 0; j < dir.files.length; j++) { - formData.push(convertFileEntryToFormData(dir.files[j], newPath)); - } - const rest = convertDirectoryEntryToFormData(dir.directories, newPath); - formData = formData.concat(rest); - } - return formData; -} - -function convertFileEntryToFormData( - fileEntry: FileEntry, - path: string -): FormDataEntry { - return { - key: fileEntry.name, - data: fileEntry.data, - opts: { - contentType: "application/octet-stream", - fileName: encodeURIComponent(path + fileEntry.name), - }, - }; -} - -export function convertDirectoryBlobToFormData( - directoryBlob: DirectoryBlob -): FormDataEntry[] { - let formData: FormDataEntry[] = []; - const files = directoryBlob.files; - - for (let i = 0; i < files.length; i++) { - formData.push(convertFileEntryToFormData(files[i], "")); - } - - if (directoryBlob.directories.length != 0) { - const dirFormData = convertDirectoryEntryToFormData( - directoryBlob.directories, - "" - ); - formData = formData.concat(dirFormData); - } - return formData; -} diff --git a/packages/cli/src/lib/deployers/ipfs/index.ts b/packages/cli/src/lib/deployers/ipfs/index.ts index eb61efa66c..6c1a8981fd 100644 --- a/packages/cli/src/lib/deployers/ipfs/index.ts +++ b/packages/cli/src/lib/deployers/ipfs/index.ts @@ -1,22 +1,12 @@ import { Deployer } from "../../deploy/deployer"; -import { convertDirectoryBlobToFormData } from "./formData"; -import { parseAddDirectoryResponse } from "./utils"; -import { convertDirectoryToEntry, DirectoryBlob } from "./file"; -import FormData from "form-data"; -import axios from "axios"; import { Uri } from "@web3api/core-js"; -const isValidUri = (uri: Uri) => uri.authority === "fs"; - -const resolveBuildDir = (buildDirPath: string): DirectoryBlob => { - const dirEntry = convertDirectoryToEntry(buildDirPath); +// eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires,@typescript-eslint/naming-convention +const IPFSClient = require("ipfs-http-client"); +const { globSource } = IPFSClient; - return { - files: [], - directories: [dirEntry], - }; -}; +const isValidUri = (uri: Uri) => uri.authority === "fs"; class IPFSDeployer implements Deployer { async execute(uri: Uri, config?: { gatewayUri: string }): Promise { @@ -27,54 +17,30 @@ class IPFSDeployer implements Deployer { } const path = uri.path; - const buildDirBlob = resolveBuildDir(path); const ipfsUrl = config?.gatewayUri ?? "http://localhost:5001"; - const formDataEntries = convertDirectoryBlobToFormData(buildDirBlob); - - const fd = new FormData(); + const client = new IPFSClient({ url: ipfsUrl }); + const globOptions = { + recursive: true, + }; - formDataEntries.forEach((formDataEntry) => { - const options: FormData.AppendOptions = {}; - if (formDataEntry.opts) { - if ( - formDataEntry.opts.contentType && - formDataEntry.opts.contentType != "" - ) { - options.contentType = formDataEntry.opts.contentType; - } - if (formDataEntry.opts.fileName && formDataEntry.opts.fileName != "") { - options.filename = formDataEntry.opts.fileName; - } - if (formDataEntry.opts.filePath && formDataEntry.opts.filePath != "") { - options.filepath = formDataEntry.opts.filePath; - } - } - const elementData = - formDataEntry.data == null ? Buffer.alloc(0) : formDataEntry.data; - fd.append(formDataEntry.key, elementData, options); - }); - - const resp = await axios.post(`${ipfsUrl}/api/v0/add`, fd, { - headers: { - ...fd.getHeaders(), - }, - }); + const addOptions = { + wrapWithDirectory: false, + }; - if (resp.status === 200) { - const directoryCID = parseAddDirectoryResponse(resp.data).find( - (a) => !a.name.includes("/") - )?.hash; + let rootCID = ""; - if (!directoryCID) { - throw new Error("Could not find root folder's CID"); + for await (const file of client.addAll( + globSource(path, globOptions), + addOptions + )) { + if (file.path.indexOf("/") === -1) { + rootCID = file.cid.toString(); } - - return new Uri(`w3://ipfs/${directoryCID}`); - } else { - throw new Error("Unexpected error: " + resp.status); } + + return new Uri(`w3://ipfs/${rootCID}`); } } diff --git a/packages/cli/src/lib/deployers/ipfs/utils.ts b/packages/cli/src/lib/deployers/ipfs/utils.ts deleted file mode 100644 index a3742aef2a..0000000000 --- a/packages/cli/src/lib/deployers/ipfs/utils.ts +++ /dev/null @@ -1,27 +0,0 @@ -export interface AddResult { - name: string; - hash: string; - size: string; -} - -export function parseAddDirectoryResponse(body: string): AddResult[] { - const results: AddResult[] = []; - const rawResults = body.split("\n"); - for (let i = 0; i < rawResults.length - 1; i++) { - const parsedResult = parseAddResponse(rawResults[i]); - results.push(parsedResult); - } - return results; -} - -function parseAddResponse(body: string): AddResult { - const addResult: AddResult = { name: "", hash: "", size: "" }; - if (body != null) { - const responseObj = JSON.parse(body); - - addResult.name = responseObj["Name"]; - addResult.hash = responseObj["Hash"]; - addResult.size = responseObj["Size"]; - } - return addResult; -} diff --git a/yarn.lock b/yarn.lock index ed398b3fe7..8fd103ffb2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2191,11 +2191,11 @@ tslib "~2.1.0" "@graphql-tools/import@^6.2.6": - version "6.6.12" - resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.6.12.tgz#73e7d43124e1ac0065f5118da8375b626fb9ad54" - integrity sha512-M0detzy3ihJGJbo7MZ6j02198o2nBhiY2MpnWEMRtUMgmZgz5ZTctK3lIxMsd+6LU96m+mc1i2MNIruTHQ6czw== + version "6.6.13" + resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.6.13.tgz#5561204a16ce3d1308aa96fb5e54cd1e550c748c" + integrity sha512-yqdCem+ZZFVAaIC2IxWyAXSEHLNPIuMzm4avTQe/LbYNRFRTpzyIYo3clc22ixeuh2LqSL3tLXKq2IsggCAeQw== dependencies: - "@graphql-tools/utils" "8.6.8" + "@graphql-tools/utils" "8.6.9" resolve-from "5.0.0" tslib "~2.3.0" @@ -2231,12 +2231,12 @@ "@graphql-tools/utils" "^7.7.0" tslib "~2.2.0" -"@graphql-tools/merge@8.2.9": - version "8.2.9" - resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.9.tgz#f4bb6ca58d0d89dbfa4fded6a1457bb359de1450" - integrity sha512-mHRrqMc1NTL6MALBQK1DmAzSxJIKoaCaW7ZCk5bRGzVj/MNQz3OsqlDb/+t9/ONT0V+WI/uxBFsrLMwa4p6L7A== +"@graphql-tools/merge@8.2.10": + version "8.2.10" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.10.tgz#fe2fe5ad33dc2d1b0af8751c0c08d18bb6bb6d88" + integrity sha512-wpg22seOTNfkIO8jFAgo8w1BsT3IS2OTMpkCNf+dvcKSP09SVidYCOliyWHgjDCmpCrvvSjOX855NUKDx/Biew== dependencies: - "@graphql-tools/utils" "8.6.8" + "@graphql-tools/utils" "8.6.9" tslib "~2.3.0" "@graphql-tools/merge@^6.2.12": @@ -2258,12 +2258,12 @@ value-or-promise "1.0.6" "@graphql-tools/schema@^8.0.2": - version "8.3.9" - resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.9.tgz#2b83464a0ef083c92d7076da0fa5939f2f5a1e34" - integrity sha512-9YFCzn0sYAGTWhZrVYY/neK5cie3s0dNm7Qq38tkhOh2ME5BtHW/8ZIq+UrLGKsBYwa+Qjb/UojGWUm2yG/z6Q== + version "8.3.10" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.10.tgz#c3e373e6ad854f533fc7e55859dd8f9e81de30dd" + integrity sha512-tfhjSTi3OzheDrVzG7rkPZg2BbQjmZRLM2vvQoM2b1TnUwgUIbpAgcnf+AWDLRsoCOWlezeLgij1BLeAR0Q0jg== dependencies: - "@graphql-tools/merge" "8.2.9" - "@graphql-tools/utils" "8.6.8" + "@graphql-tools/merge" "8.2.10" + "@graphql-tools/utils" "8.6.9" tslib "~2.3.0" value-or-promise "1.0.11" @@ -2299,10 +2299,10 @@ dependencies: tslib "~2.3.0" -"@graphql-tools/utils@8.6.8": - version "8.6.8" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.6.8.tgz#a0824ed5810f66c504df4e97c5900786ac0c260e" - integrity sha512-EdUUeKi/wp/UvuknyINpQ/uXDqTM3qxPPPDIq5RpfW0zQOeCvbZcx8xHoMox0TYKvKtg3zoB7aprUtoW+iZLxw== +"@graphql-tools/utils@8.6.9": + version "8.6.9" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.6.9.tgz#fe1b81df29c9418b41b7a1ffe731710b93d3a1fe" + integrity sha512-Z1X4d4GCT81+8CSt6SgU4t1w1UAUsAIRb67mI90k/zAs+ArkB95iE3bWXuJCUmd1+r8DGGtmUNOArtd6wkt+OQ== dependencies: tslib "~2.3.0" @@ -2893,9 +2893,9 @@ integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== "@jridgewell/trace-mapping@^0.3.0": - version "0.3.4" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" - integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== + version "0.3.7" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.7.tgz#941982134e9b7fad031c857ccfc4a0634fc6a471" + integrity sha512-8XC0l0PwCbdg2Uc8zIIf6djNX3lYiz9GqQlC1LJ9WQvTYvcfP8IA9K2IKRnPm5tAX6X/+orF+WwKZ0doGcgJlg== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" @@ -4310,9 +4310,9 @@ integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/lodash@^4.14.168": - version "4.14.181" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.181.tgz#d1d3740c379fda17ab175165ba04e2d03389385d" - integrity sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag== + version "4.14.182" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2" + integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q== "@types/minimatch@*", "@types/minimatch@^3.0.3": version "3.0.5" @@ -7690,17 +7690,17 @@ copyfiles@2.4.1: yargs "^16.1.0" core-js-compat@^3.0.0, core-js-compat@^3.20.2, core-js-compat@^3.21.0, core-js-compat@^3.6.2: - version "3.22.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.0.tgz#7ce17ab57c378be2c717c7c8ed8f82a50a25b3e4" - integrity sha512-WwA7xbfRGrk8BGaaHlakauVXrlYmAIkk8PNGb1FDQS+Rbrewc3pgFfwJFRw6psmJVAll7Px9UHRYE16oRQnwAQ== + version "3.22.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.1.tgz#47b9c5e79efbf13935f637449fa1cdec8cd9515f" + integrity sha512-CWbNqTluLMvZg1cjsQUbGiCM91dobSHKfDIyCoxuqxthdjGuUlaMbCsSehP3CBiVvG0C7P6UIrC1v0hgFE75jw== dependencies: browserslist "^4.20.2" semver "7.0.0" core-js-pure@^3.20.2: - version "3.22.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.0.tgz#0eaa54b6d1f4ebb4d19976bb4916dfad149a3747" - integrity sha512-ylOC9nVy0ak1N+fPIZj00umoZHgUVqmucklP5RT5N+vJof38klKn8Ze6KGyvchdClvEBr6LcQqJpI216LUMqYA== + version "3.22.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.1.tgz#4d94e0c9a7b710da20dadd727fe98b43543119f0" + integrity sha512-TChjCtgcMDc8t12RiwAsThjqrS/VpBlEvDgL009ot4HESzBo3h2FSZNa6ZS1nWKZEPDoulnszxUll9n0/spflQ== core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5: version "2.6.12" @@ -7708,9 +7708,9 @@ core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.5.0: - version "3.22.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.0.tgz#b52007870c5e091517352e833b77f0b2d2b259f3" - integrity sha512-8h9jBweRjMiY+ORO7bdWSeWfHhLPO7whobj7Z2Bl0IDo00C228EdGgH7FE4jGumbEjzcFfkfW8bXgdkEDhnwHQ== + version "3.22.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.1.tgz#1936e4f1da82675fe22ae10ee60ef638cd9752fd" + integrity sha512-l6CwCLq7XgITOQGhv1dIUmwCFoqFjyQ6zQHUCQlS0xKmb9d6OHIg8jDiEoswhaettT21BSF5qKr6kbvE+aKwxw== core-util-is@1.0.2: version "1.0.2" @@ -8725,9 +8725,9 @@ electron-fetch@^1.7.2: encoding "^0.1.13" electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.47, electron-to-chromium@^1.4.84: - version "1.4.111" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.111.tgz#897613f6504f3f17c9381c7499a635b413e4df4e" - integrity sha512-/s3+fwhKf1YK4k7btOImOzCQLpUjS6MaPf0ODTNuT4eTM1Bg4itBpLkydhOzJmpmH6Z9eXFyuuK5czsmzRzwtw== + version "1.4.114" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.114.tgz#d85ec0808dd50b0cf6e6b262480ffd385f71c873" + integrity sha512-gRwLpVYWHGbERPU6o8pKfR168V6enWEXzZc6zQNNXbgJ7UJna+9qzAIHY94+9KOv71D/CH+QebLA9pChD2q8zA== elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" @@ -8926,9 +8926,9 @@ es-to-primitive@^1.2.1: is-symbol "^1.0.2" es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.59, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.60" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.60.tgz#e8060a86472842b93019c31c34865012449883f4" - integrity sha512-jpKNXIt60htYG59/9FGf2PYT3pwMpnEbNKysU+k/4FGwyGtMotOvcZOuW+EmXXYASRqYSXQfGL5cVIthOTgbkg== + version "0.10.61" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.61.tgz#311de37949ef86b6b0dcea894d1ffedb909d3269" + integrity sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA== dependencies: es6-iterator "^2.0.3" es6-symbol "^3.1.3" @@ -10426,9 +10426,9 @@ functional-red-black-tree@^1.0.1: integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= functions-have-names@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21" - integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== ganache-cli@^6.1.0: version "6.12.2" @@ -10924,9 +10924,9 @@ has-ansi@^2.0.0: ansi-regex "^2.0.0" 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== + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== has-flag@^2.0.0: version "2.0.0" @@ -11848,9 +11848,9 @@ is-color-stop@^1.0.0: rgba-regex "^1.0.0" is-core-module@^2.5.0, is-core-module@^2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" - integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== dependencies: has "^1.0.3" From bd8f4a44849a67f7ab50d65a8fd0fbdb1deb1987 Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 20 Apr 2022 15:00:43 +0200 Subject: [PATCH 24/41] (fix): updated buildAndDeploy API function to use deploy command --- .../js/test-env/ens-wrapper/mutation.wasm | Bin 0 -> 213422 bytes packages/js/test-env/ens-wrapper/query.wasm | Bin 0 -> 92884 bytes .../js/test-env/ens-wrapper/schema.graphql | 709 ++++++++++++++++++ .../test-env/ens-wrapper/web3api.build.json | 6 + packages/js/test-env/ens-wrapper/web3api.json | 16 + packages/js/test-env/package.json | 6 +- packages/js/test-env/src/index.ts | 23 +- 7 files changed, 749 insertions(+), 11 deletions(-) create mode 100644 packages/js/test-env/ens-wrapper/mutation.wasm create mode 100644 packages/js/test-env/ens-wrapper/query.wasm create mode 100644 packages/js/test-env/ens-wrapper/schema.graphql create mode 100644 packages/js/test-env/ens-wrapper/web3api.build.json create mode 100644 packages/js/test-env/ens-wrapper/web3api.json diff --git a/packages/js/test-env/ens-wrapper/mutation.wasm b/packages/js/test-env/ens-wrapper/mutation.wasm new file mode 100644 index 0000000000000000000000000000000000000000..df308c48b57689c68c6aa7219eb6947aa0185a39 GIT binary patch literal 213422 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 literal 0 HcmV?d00001 diff --git a/packages/js/test-env/ens-wrapper/query.wasm b/packages/js/test-env/ens-wrapper/query.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6d61eac356922eca019523d7b920717b31b3bc7f GIT binary patch literal 92884 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 KqZw5x|NjHraauwE literal 0 HcmV?d00001 diff --git a/packages/js/test-env/ens-wrapper/schema.graphql b/packages/js/test-env/ens-wrapper/schema.graphql new file mode 100644 index 0000000000..84d0bb99d9 --- /dev/null +++ b/packages/js/test-env/ens-wrapper/schema.graphql @@ -0,0 +1,709 @@ +### Web3API Header START ### +scalar UInt +scalar UInt8 +scalar UInt16 +scalar UInt32 +scalar Int +scalar Int8 +scalar Int16 +scalar Int32 +scalar Bytes +scalar BigInt +scalar JSON +scalar Map + +directive @imported( + uri: String! + namespace: String! + nativeType: String! +) on OBJECT | ENUM + +directive @imports( + types: [String!]! +) on OBJECT + +directive @capability( + type: String! + uri: String! + namespace: String! +) repeatable on OBJECT + +directive @enabled_interface on OBJECT + +directive @annotate(type: String!) on FIELD + +### Web3API Header END ### + +type Query @imports( + types: [ + "Ethereum_Query", + "Ethereum_Connection", + "Ethereum_TxOverrides", + "Ethereum_StaticTxResult", + "Ethereum_TxRequest", + "Ethereum_TxReceipt", + "Ethereum_Log", + "Ethereum_EventNotification", + "Ethereum_Network", + "UTS46_Query", + "UTS46_ConvertResult", + "SHA3_Query" + ] +) { + getResolver( + registryAddress: String! + domain: String! + connection: Ethereum_Connection + ): String! + + getOwner( + domain: String! + registryAddress: String! + connection: Ethereum_Connection + ): String! + + getAddress( + domain: String! + resolverAddress: String! + connection: Ethereum_Connection + ): String! + + getAddressFromDomain( + domain: String! + registryAddress: String! + connection: Ethereum_Connection + ): String! + + getContentHash( + domain: String! + resolverAddress: String! + connection: Ethereum_Connection + ): String! + + getContentHashFromDomain( + domain: String! + registryAddress: String! + connection: Ethereum_Connection + ): String! + + getExpiryTimes( + domain: String! + registrarAddress: String! + connection: Ethereum_Connection + ): String! + + getReverseResolver( + address: String! + registryAddress: String! + connection: Ethereum_Connection + ): String! + + getNameFromReverseResolver( + address: String! + resolverAddress: String! + connection: Ethereum_Connection + ): String! + + getNameFromAddress( + address: String! + registryAddress: String! + connection: Ethereum_Connection + ): String! + + getTextRecord( + domain: String! + resolverAddress: String! + key: String! + connection: Ethereum_Connection + ): String! +} + +type Mutation @imports( + types: [ + "Ethereum_Mutation", + "Ethereum_Connection", + "Ethereum_TxOverrides", + "Ethereum_TxResponse", + "Ethereum_Access", + "Ethereum_TxReceipt", + "Ethereum_Log", + "Ethereum_TxRequest", + "UTS46_Query", + "UTS46_ConvertResult", + "SHA3_Query" + ] +) { + setResolver( + domain: String! + resolverAddress: String! + registryAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + registerDomain( + domain: String! + registrarAddress: String! + registryAddress: String! + owner: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + reverseRegisterDomain( + domain: String! + reverseRegistryAddress: String! + owner: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + setName( + domain: String! + reverseRegistryAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + setAddress( + domain: String! + address: String! + resolverAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + setOwner( + domain: String! + newOwner: String! + registryAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + setSubdomainOwner( + subdomain: String! + owner: String! + registryAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + setRecord( + domain: String! + owner: String! + resolverAddress: String! + ttl: String! + registryAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + setSubdomainRecord( + domain: String! + label: String! + owner: String! + resolverAddress: String! + ttl: String! + registryAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + setContentHash( + domain: String! + cid: String! + resolverAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + setAddressFromDomain( + domain: String! + address: String! + registryAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + setContentHashFromDomain( + domain: String! + cid: String! + registryAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + deployFIFSRegistrar( + registryAddress: String! + tld: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): String! + + registerSubnodeOwnerWithFIFSRegistrar( + label: String! + owner: String! + fifsRegistrarAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + setTextRecord( + domain: String! + resolverAddress: String! + key: String! + value: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): Ethereum_TxResponse! + + configureOpenDomain( + tld: String! + owner: String! + registryAddress: String! + resolverAddress: String! + registrarAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): ConfigureOpenDomainResponse! + + createSubdomainInOpenDomain( + label: String! + domain: String! + owner: String! + fifsRegistrarAddress: String! + registryAddress: String! + resolverAddress: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): CreateSubdomainInOpenDomainResponse! + + createSubdomainInOpenDomainAndSetContentHash( + label: String! + domain: String! + owner: String! + fifsRegistrarAddress: String! + registryAddress: String! + resolverAddress: String! + cid: String! + connection: Ethereum_Connection + txOverrides: TxOverrides + ): CreateSubdomainInOpenDomainAndSetContentHashResponse +} + +type ConfigureOpenDomainResponse { + fifsRegistrarAddress: String! + registerOpenDomainTxReceipt: Ethereum_TxResponse! + setSubdomainRecordTxReceipt: Ethereum_TxResponse! +} + +type CreateSubdomainInOpenDomainResponse { + registerSubdomainTxReceipt: Ethereum_TxResponse! + setResolverTxReceipt: Ethereum_TxResponse! +} + +type CreateSubdomainInOpenDomainAndSetContentHashResponse implements CreateSubdomainInOpenDomainResponse { + setContentHashReceiptTx: Ethereum_TxResponse! + registerSubdomainTxReceipt: Ethereum_TxResponse! + setResolverTxReceipt: Ethereum_TxResponse! +} + +type TxOverrides { + gasPrice: BigInt + gasLimit: BigInt +} + +### Imported Queries START ### + +type Ethereum_Query @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Query" +) { + callContractView( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + ): String! + + callContractStatic( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + txOverrides: Ethereum_TxOverrides + ): Ethereum_StaticTxResult! + + getBalance( + address: String! + blockTag: BigInt + connection: Ethereum_Connection + ): BigInt! + + encodeParams( + types: [String!]! + values: [String!]! + ): String! + + encodeFunction( + method: String! + args: [String!] + ): String! + + solidityPack( + types: [String!]! + values: [String!]! + ): String! + + solidityKeccak256( + types: [String!]! + values: [String!]! + ): String! + + soliditySha256( + types: [String!]! + values: [String!]! + ): String! + + getSignerAddress( + connection: Ethereum_Connection + ): String! + + getSignerBalance( + blockTag: BigInt + connection: Ethereum_Connection + ): BigInt! + + getSignerTransactionCount( + blockTag: BigInt + connection: Ethereum_Connection + ): BigInt! + + getGasPrice( + connection: Ethereum_Connection + ): BigInt! + + estimateTransactionGas( + tx: Ethereum_TxRequest! + connection: Ethereum_Connection + ): BigInt! + + estimateContractCallGas( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + txOverrides: Ethereum_TxOverrides + ): BigInt! + + checkAddress( + address: String! + ): Boolean! + + toWei( + eth: String! + ): BigInt! + + toEth( + wei: BigInt! + ): String! + + awaitTransaction( + txHash: String! + confirmations: UInt32! + timeout: UInt32! + connection: Ethereum_Connection + ): Ethereum_TxReceipt! + + waitForEvent( + address: String! + event: String! + args: [String!] + timeout: UInt32 + connection: Ethereum_Connection + ): Ethereum_EventNotification! + + getNetwork( + connection: Ethereum_Connection + ): Ethereum_Network! +} + +type UTS46_Query @imported( + uri: "w3://ens/uts46.web3api.eth", + namespace: "UTS46", + nativeType: "Query" +) { + toAscii( + value: String! + ): String! + + toUnicode( + value: String! + ): String! + + convert( + value: String! + ): UTS46_ConvertResult! +} + +type SHA3_Query @imported( + uri: "w3://ens/sha3.web3api.eth", + namespace: "SHA3", + nativeType: "Query" +) { + sha3_512( + message: String! + ): String! + + sha3_384( + message: String! + ): String! + + sha3_256( + message: String! + ): String! + + sha3_224( + message: String! + ): String! + + keccak_512( + message: String! + ): String! + + keccak_384( + message: String! + ): String! + + keccak_256( + message: String! + ): String! + + keccak_224( + message: String! + ): String! + + hex_keccak_256( + message: String! + ): String! + + buffer_keccak_256( + message: Bytes! + ): String! + + shake_128( + message: String! + outputBits: Int! + ): String! + + shake_256( + message: String! + outputBits: Int! + ): String! +} + +type Ethereum_Mutation @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Mutation" +) { + callContractMethod( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + txOverrides: Ethereum_TxOverrides + ): Ethereum_TxResponse! + + callContractMethodAndWait( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + txOverrides: Ethereum_TxOverrides + ): Ethereum_TxReceipt! + + sendTransaction( + tx: Ethereum_TxRequest! + connection: Ethereum_Connection + ): Ethereum_TxResponse! + + sendTransactionAndWait( + tx: Ethereum_TxRequest! + connection: Ethereum_Connection + ): Ethereum_TxReceipt! + + deployContract( + abi: String! + bytecode: String! + args: [String!] + connection: Ethereum_Connection + ): String! + + signMessage( + message: String! + connection: Ethereum_Connection + ): String! + + sendRPC( + method: String! + params: [String!]! + connection: Ethereum_Connection + ): String +} + +### Imported Queries END ### + +### Imported Objects START ### + +type Ethereum_Connection @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Connection" +) { + node: String + networkNameOrChainId: String +} + +type Ethereum_TxOverrides @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "TxOverrides" +) { + gasLimit: BigInt + gasPrice: BigInt + value: BigInt +} + +type Ethereum_StaticTxResult @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "StaticTxResult" +) { + result: String! + error: Boolean! +} + +type Ethereum_TxRequest @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "TxRequest" +) { + to: String + from: String + nonce: UInt32 + gasLimit: BigInt + gasPrice: BigInt + data: String + value: BigInt + chainId: BigInt + type: UInt32 +} + +type Ethereum_TxReceipt @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "TxReceipt" +) { + to: String! + from: String! + contractAddress: String! + transactionIndex: UInt32! + root: String + gasUsed: BigInt! + logsBloom: String! + transactionHash: String! + logs: [Ethereum_Log!]! + blockNumber: BigInt! + blockHash: String! + confirmations: UInt32! + cumulativeGasUsed: BigInt! + effectiveGasPrice: BigInt! + byzantium: Boolean! + type: UInt32! + status: UInt32 +} + +type Ethereum_Log @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Log" +) { + blockNumber: BigInt! + blockHash: String! + transactionIndex: UInt32! + removed: Boolean! + address: String! + data: String! + topics: [String!]! + transactionHash: String! + logIndex: UInt32! +} + +type Ethereum_EventNotification @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "EventNotification" +) { + data: String! + address: String! + log: Ethereum_Log! +} + +type Ethereum_Network @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Network" +) { + name: String! + chainId: BigInt! + ensAddress: String +} + +type UTS46_ConvertResult @imported( + uri: "w3://ens/uts46.web3api.eth", + namespace: "UTS46", + nativeType: "ConvertResult" +) { + IDN: String! + PC: String! +} + +type Ethereum_TxResponse @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "TxResponse" +) { + hash: String! + to: String + from: String! + nonce: UInt32! + gasLimit: BigInt! + gasPrice: BigInt + data: String! + value: BigInt! + chainId: BigInt! + blockNumber: BigInt + blockHash: String + timestamp: UInt32 + confirmations: UInt32! + raw: String + r: String + s: String + v: UInt32 + type: UInt32 + accessList: [Ethereum_Access!] +} + +type Ethereum_Access @imported( + uri: "w3://ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Access" +) { + address: String! + storageKeys: [String!]! +} + +### Imported Objects END ### diff --git a/packages/js/test-env/ens-wrapper/web3api.build.json b/packages/js/test-env/ens-wrapper/web3api.build.json new file mode 100644 index 0000000000..f19dc23c6c --- /dev/null +++ b/packages/js/test-env/ens-wrapper/web3api.build.json @@ -0,0 +1,6 @@ +{ + "format": "0.0.1-prealpha.2", + "docker": { + "buildImageId": "sha256:b2b93ec62f13faae089d7bb52b0140948e00da52bf55e1cdb589826946ec92be\n" + } +} \ No newline at end of file diff --git a/packages/js/test-env/ens-wrapper/web3api.json b/packages/js/test-env/ens-wrapper/web3api.json new file mode 100644 index 0000000000..10919ef155 --- /dev/null +++ b/packages/js/test-env/ens-wrapper/web3api.json @@ -0,0 +1,16 @@ +{ + "format": "0.0.1-prealpha.7", + "language": "wasm/assemblyscript", + "build": "./web3api.build.json", + "modules": { + "mutation": { + "module": "./mutation.wasm", + "schema": "./schema.graphql" + }, + "query": { + "module": "./query.wasm", + "schema": "./schema.graphql" + } + }, + "name": "Unnamed" +} \ No newline at end of file diff --git a/packages/js/test-env/package.json b/packages/js/test-env/package.json index 76e062cff6..d08f996c8d 100644 --- a/packages/js/test-env/package.json +++ b/packages/js/test-env/package.json @@ -12,7 +12,8 @@ "build" ], "scripts": { - "build": "rimraf ./build && tsc --project tsconfig.build.json", + "build": "rimraf ./build && tsc --project tsconfig.build.json && yarn build:enswrapper", + "build:enswrapper": "copyfiles ./ens-wrapper/* ./build/ens-wrapper -u 1", "lint": "eslint --color -c ../../../.eslintrc.js src/" }, "dependencies": { @@ -25,7 +26,8 @@ "devDependencies": { "rimraf": "3.0.2", "ts-node": "8.10.2", - "typescript": "4.0.7" + "typescript": "4.0.7", + "copyfiles": "2.4.1" }, "gitHead": "7346adaf5adb7e6bbb70d9247583e995650d390a", "publishConfig": { diff --git a/packages/js/test-env/src/index.ts b/packages/js/test-env/src/index.ts index 2960a8d25c..15eecd9352 100644 --- a/packages/js/test-env/src/index.ts +++ b/packages/js/test-env/src/index.ts @@ -2,7 +2,7 @@ import path from "path"; import spawn from "spawn-command"; import axios from "axios"; import fs from "fs"; -import ethers from "ethers"; +import { ethers } from "ethers"; import yaml from "js-yaml"; import { Client, deserializeWeb3ApiManifest } from "@web3api/core-js"; @@ -17,6 +17,7 @@ interface TestEnvironment { const monorepoCli = `${__dirname}/../../../cli/bin/w3`; const npmCli = `${__dirname}/../../cli/bin/w3`; +const ensWrapperPath = `${__dirname}/ens-wrapper`; export const initTestEnvironment = async ( cli?: string @@ -189,7 +190,7 @@ export async function buildAndDeployApi({ // TODO: deploy ENS wrapper to testenv const { error: registerError } = await client.invoke({ - uri: ensUri, + uri: `fs/${ensWrapperPath}`, module: "mutation", method: "registerDomain", input: { @@ -210,7 +211,7 @@ export async function buildAndDeployApi({ } const { error: setResolverError } = await client.invoke({ - uri: ensUri, + uri: `fs/${ensWrapperPath}`, module: "mutation", method: "setResolver", input: { @@ -232,7 +233,7 @@ export async function buildAndDeployApi({ // manually configure manifests const web3apiManifest = deserializeWeb3ApiManifest( - fs.readFileSync(path.join(apiAbsPath, "web3api.yaml"), "utf-8") + fs.readFileSync(manifestPath, "utf-8") ); const useTempManifests = !web3apiManifest.deploy; @@ -240,20 +241,24 @@ export async function buildAndDeployApi({ if (useTempManifests) { fs.writeFileSync( tempManifestPath, - yaml.safeDump({ - ...web3apiManifest, - deploy: `./${tempManifestFilename}`, + yaml.dump({ + format: web3apiManifest.format, + name: web3apiManifest.name, + build: web3apiManifest.build, + language: web3apiManifest.language, + modules: web3apiManifest.modules, + deploy: `./${tempDeployManifestFilename}`, }) ); fs.writeFileSync( tempDeployManifestPath, - yaml.safeDump({ + yaml.dump({ format: "0.0.1-prealpha.1", stages: { ipfsDeploy: { package: "ipfs", - uri: "fs/./build", + uri: `fs/${apiAbsPath}/build`, config: { gatewayUri: ipfsProvider, }, From f421688396b0e9656fdd96ebac43154d5fce0d41 Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 20 Apr 2022 15:01:30 +0200 Subject: [PATCH 25/41] (chore): updated ethereum plugin tests --- .../plugins/ethereum/src/__tests__/e2e.spec.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts b/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts index baab0d4c1a..8b95e7c8a4 100644 --- a/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts +++ b/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts @@ -7,7 +7,7 @@ import { ipfsPlugin } from "@web3api/ipfs-plugin-js"; import { initTestEnvironment, stopTestEnvironment, - buildAndDeployApi + buildAndDeployApi, } from "@web3api/test-env-js"; import { Wallet } from "ethers"; @@ -77,11 +77,15 @@ describe("Ethereum Plugin", () => { ], }); - const api = await buildAndDeployApi( - `${__dirname}/integration`, - ipfs, - ensAddress - ); + const api = await buildAndDeployApi({ + apiAbsPath: `${__dirname}/integration`, + ipfsProvider: ipfs, + ensRegistryAddress: ensAddress, + ensRegistrarAddress: registrarAddress, + ensResolverAddress: resolverAddress, + client, + ethereumProvider: ethereum, + }); uri = `ens/testnet/${api.ensDomain}`; }); @@ -162,7 +166,7 @@ describe("Ethereum Plugin", () => { expect(response.errors).toBeUndefined(); expect(response.data?.callContractStatic).toBeDefined(); expect(response.data?.callContractStatic.error).toBeTruthy(); - expect(response.data?.callContractStatic.result).toBe("missing revert data in call exception"); + expect(response.data?.callContractStatic.result).toContain("missing revert data in call exception"); }); it("getBalance", async () => { From 25cbc514e67f686435e0d1d9b996bfc4d7b0a87a Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 20 Apr 2022 17:09:01 +0200 Subject: [PATCH 26/41] (chore): updated buildAndDeployApi test usages --- .../client/src/__tests__/resolveUri.spec.ts | 72 +++++++++++++------ .../filesystem/src/__tests__/e2e.spec.ts | 18 ++++- .../src/__tests__/e2e/integration.spec.ts | 17 +++-- .../react/src/__tests__/integration.spec.tsx | 35 +++++++-- .../src/__tests__/useWeb3ApiInvoke.spec.tsx | 36 ++++++++-- .../src/__tests__/useWeb3ApiQuery.spec.tsx | 36 ++++++++-- .../src/__tests__/e2e/integration.spec.ts | 16 ++++- .../api/assemblyscript/src/__tests__/utils.ts | 7 -- 8 files changed, 182 insertions(+), 55 deletions(-) diff --git a/packages/js/client/src/__tests__/resolveUri.spec.ts b/packages/js/client/src/__tests__/resolveUri.spec.ts index 10a87f739a..6dff764019 100644 --- a/packages/js/client/src/__tests__/resolveUri.spec.ts +++ b/packages/js/client/src/__tests__/resolveUri.spec.ts @@ -20,6 +20,8 @@ describe("Web3ApiClient - resolveUri", () => { let ipfsProvider: string; let ethProvider: string; let ensAddress: string; + let ensRegistrarAddress: string; + let ensResolverAddress: string; beforeAll(async () => { const { ipfs, ethereum, ensAddress: ens } = await initTestEnvironment(); @@ -251,11 +253,16 @@ describe("Web3ApiClient - resolveUri", () => { const client = await getClient(); - const deployResult = await buildAndDeployApi( - `${GetPathToTestApis()}/interface-invoke/test-api`, + const deployResult = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/interface-invoke/test-api`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); + const ensUri = new Uri(`ens/testnet/${deployResult.ensDomain}`); const ipfsUri = new Uri(`ipfs/${deployResult.ipfsCid}`); @@ -348,11 +355,16 @@ describe("Web3ApiClient - resolveUri", () => { const client = await getClient(); - const deployResult = await buildAndDeployApi( - `${GetPathToTestApis()}/interface-invoke/test-api`, + const deployResult = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/interface-invoke/test-api`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); + const ensUri = new Uri(`ens/testnet/${deployResult.ensDomain}`); const ipfsUri = new Uri(`ipfs/${deployResult.ipfsCid}`); @@ -474,11 +486,16 @@ describe("Web3ApiClient - resolveUri", () => { const client = await getClient(); - const deployResult = await buildAndDeployApi( - `${GetPathToTestApis()}/interface-invoke/test-api`, + const deployResult = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/interface-invoke/test-api`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); + const ensUri = new Uri(`ens/testnet/${deployResult.ensDomain}`); const ipfsUri = new Uri(`ipfs/${deployResult.ipfsCid}`); @@ -601,11 +618,16 @@ describe("Web3ApiClient - resolveUri", () => { const client = await getClient(); - const deployResult = await buildAndDeployApi( - `${GetPathToTestApis()}/interface-invoke/test-api`, + const deployResult = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/interface-invoke/test-api`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); + const ensUri = new Uri(`ens/testnet/${deployResult.ensDomain}`); const ipfsUri = new Uri(`ipfs/${deployResult.ipfsCid}`); @@ -742,17 +764,23 @@ describe("Web3ApiClient - resolveUri", () => { cwd: `${GetPathToTestApis()}/interface-invoke/test-interface`, }); - const deployResult = await buildAndDeployApi( - `${GetPathToTestApis()}/interface-invoke/test-api`, + const client = await getClient(); + + const deployResult = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/interface-invoke/test-api`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = new Uri(`ens/testnet/${deployResult.ensDomain}`); const ipfsUri = new Uri(`ipfs/${deployResult.ipfsCid}`); const redirectUri = new Uri(`ens/redirect.eth`); - const client = await getClient({ + const clientWithRedirects = await getClient({ redirects: [ { from: ipfsUri.uri, @@ -761,7 +789,7 @@ describe("Web3ApiClient - resolveUri", () => { ], }); - const result = await client.resolveUri(ensUri); + const result = await clientWithRedirects.resolveUri(ensUri); expect(result.api).toBeFalsy(); expect(result.uri).toEqual(redirectUri); diff --git a/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts b/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts index 9b34f02fa0..b57f067350 100644 --- a/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts +++ b/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts @@ -22,11 +22,17 @@ describe("Filesystem plugin", () => { let client: Web3ApiClient; let ipfsProvider: string; let ensAddress: string; + let ethereumProvider: string; + let ensRegistrarAddress: string; + let ensResolverAddress: string; beforeAll(async () => { - const { ipfs, ethereum, ensAddress: ens } = await initTestEnvironment(); + const { ipfs, ethereum, ensAddress: ens, registrarAddress, resolverAddress } = await initTestEnvironment(); ipfsProvider = ipfs; ensAddress = ens; + ethereumProvider = ethereum; + ensRegistrarAddress = registrarAddress; + ensResolverAddress = resolverAddress; const config: Partial = { plugins: [ @@ -75,7 +81,15 @@ describe("Filesystem plugin", () => { const apiPath = path.resolve( `${GetPathToTestApis()}/simple-storage` ); - await buildAndDeployApi(apiPath, ipfsProvider, ensAddress); + await buildAndDeployApi({ + apiAbsPath: apiPath, + ipfsProvider, + ensRegistryAddress: ensAddress, + ensRegistrarAddress, + ensResolverAddress, + ethereumProvider, + client + }); const fsPath = `${apiPath}/build`; const fsUri = `fs/${fsPath}`; diff --git a/packages/js/plugins/http/src/__tests__/e2e/integration.spec.ts b/packages/js/plugins/http/src/__tests__/e2e/integration.spec.ts index 03f3e8342c..96c5d6ff3d 100644 --- a/packages/js/plugins/http/src/__tests__/e2e/integration.spec.ts +++ b/packages/js/plugins/http/src/__tests__/e2e/integration.spec.ts @@ -33,6 +33,9 @@ describe("e2e tests for HttpPlugin", () => { const { data } = await axios.get("http://localhost:4040/deploy-ens"); ensAddress = data.ensAddress + + const registrarAddress = data.registrarAddress + const resolverAddress = data.resolverAddress client = new Web3ApiClient({ plugins: [ @@ -69,11 +72,15 @@ describe("e2e tests for HttpPlugin", () => { ], }); - const api = await buildAndDeployApi( - `${__dirname}/integration`, - ipfs, - ensAddress - ); + const api = await buildAndDeployApi({ + apiAbsPath: `${__dirname}/integration`, + ipfsProvider: ipfs, + ensRegistryAddress: ensAddress, + ensRegistrarAddress: registrarAddress, + ensResolverAddress: resolverAddress, + client, + ethereumProvider: ethereum + }); uri = `ens/testnet/${api.ensDomain}`; }); diff --git a/packages/js/react/src/__tests__/integration.spec.tsx b/packages/js/react/src/__tests__/integration.spec.tsx index 6f777bbed3..7137db217d 100644 --- a/packages/js/react/src/__tests__/integration.spec.tsx +++ b/packages/js/react/src/__tests__/integration.spec.tsx @@ -13,6 +13,8 @@ import { PluginRegistration } from "@web3api/core-js"; // eslint-disable-next-line import/no-extraneous-dependencies import React from "react"; import { render, fireEvent, screen, waitFor } from "@testing-library/react"; +import { Web3ApiClient } from "@web3api/client-js"; +import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; jest.setTimeout(360000); @@ -29,15 +31,38 @@ describe("Web3API React Integration", () => { ipfs, ethereum, ensAddress, + registrarAddress, + resolverAddress } = await initTestEnvironment(); plugins = createPlugins(ensAddress, ethereum, ipfs); - api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, - ipfs, - ensAddress - ); + const client = new Web3ApiClient({ + plugins: [ + { + uri: "w3://ens/ethereum.web3api.eth", + plugin: ethereumPlugin({ + networks: { + testnet: { + provider: ethereum, + } + }, + defaultNetwork: "testnet" + }), + } + ], + }); + + api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-storage`, + ipfsProvider: ipfs, + ethereumProvider: ethereum, + ensRegistrarAddress: registrarAddress, + ensRegistryAddress: ensAddress, + ensResolverAddress: resolverAddress, + client + }); + ensUri = `ens/testnet/${api.ensDomain}`; }); diff --git a/packages/js/react/src/__tests__/useWeb3ApiInvoke.spec.tsx b/packages/js/react/src/__tests__/useWeb3ApiInvoke.spec.tsx index 2ec1a5144b..1287cc9789 100644 --- a/packages/js/react/src/__tests__/useWeb3ApiInvoke.spec.tsx +++ b/packages/js/react/src/__tests__/useWeb3ApiInvoke.spec.tsx @@ -20,6 +20,8 @@ import { RenderHookOptions, cleanup } from "@testing-library/react-hooks"; +import { Web3ApiClient } from "@web3api/client-js"; +import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; jest.setTimeout(360000); @@ -32,14 +34,36 @@ describe("useWeb3ApiInvoke hook", () => { const { ipfs, ethereum, - ensAddress + ensAddress, + registrarAddress, + resolverAddress } = await initTestEnvironment(); - const { ensDomain } = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, - ipfs, - ensAddress - ); + const client = new Web3ApiClient({ + plugins: [ + { + uri: "w3://ens/ethereum.web3api.eth", + plugin: ethereumPlugin({ + networks: { + testnet: { + provider: ethereum, + } + }, + defaultNetwork: "testnet" + }), + } + ], + }); + + const { ensDomain } = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-storage`, + ipfsProvider: ipfs, + ethereumProvider: ethereum, + ensRegistrarAddress: registrarAddress, + ensRegistryAddress: ensAddress, + ensResolverAddress: resolverAddress, + client + }); uri = `ens/testnet/${ensDomain}`; plugins = createPlugins(ensAddress, ethereum, ipfs); diff --git a/packages/js/react/src/__tests__/useWeb3ApiQuery.spec.tsx b/packages/js/react/src/__tests__/useWeb3ApiQuery.spec.tsx index cd83e290ae..f36cf23467 100644 --- a/packages/js/react/src/__tests__/useWeb3ApiQuery.spec.tsx +++ b/packages/js/react/src/__tests__/useWeb3ApiQuery.spec.tsx @@ -22,6 +22,8 @@ import { RenderHookOptions, cleanup } from "@testing-library/react-hooks"; +import { Web3ApiClient } from "@web3api/client-js"; +import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; jest.setTimeout(360000); @@ -34,14 +36,36 @@ describe("useWeb3ApiQuery hook", () => { const { ipfs, ethereum, - ensAddress + ensAddress, + registrarAddress, + resolverAddress } = await initTestEnvironment(); - const { ensDomain } = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, - ipfs, - ensAddress - ); + const client = new Web3ApiClient({ + plugins: [ + { + uri: "w3://ens/ethereum.web3api.eth", + plugin: ethereumPlugin({ + networks: { + testnet: { + provider: ethereum, + } + }, + defaultNetwork: "testnet" + }), + } + ], + }); + + const { ensDomain } = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-storage`, + ipfsProvider: ipfs, + ethereumProvider: ethereum, + ensRegistrarAddress: registrarAddress, + ensRegistryAddress: ensAddress, + ensResolverAddress: resolverAddress, + client + }); uri = `ens/testnet/${ensDomain}`; plugins = createPlugins(ensAddress, ethereum, ipfs); diff --git a/packages/templates/api/assemblyscript/src/__tests__/e2e/integration.spec.ts b/packages/templates/api/assemblyscript/src/__tests__/e2e/integration.spec.ts index dd44b3790c..675bf1da8b 100644 --- a/packages/templates/api/assemblyscript/src/__tests__/e2e/integration.spec.ts +++ b/packages/templates/api/assemblyscript/src/__tests__/e2e/integration.spec.ts @@ -21,6 +21,8 @@ describe("SimpleStorage", () => { const { ethereum: testEnvEtherem, ensAddress, + registrarAddress, + resolverAddress, ipfs, } = await initTestEnvironment(); // deploy api @@ -30,12 +32,22 @@ describe("SimpleStorage", () => { "..", ".." ); - const api = await buildAndDeployApi(apiPath, ipfs, ensAddress); - ensUri = `ens/testnet/${api.ensDomain}`; // get client const config = getPlugins(testEnvEtherem, ipfs, ensAddress); client = new Web3ApiClient(config); + + const api = await buildAndDeployApi({ + apiAbsPath: apiPath, + ipfsProvider: ipfs, + ensRegistryAddress: ensAddress, + ensRegistrarAddress: registrarAddress, + ensResolverAddress: resolverAddress, + client, + ethereumProvider: testEnvEtherem, + }); + + ensUri = `ens/testnet/${api.ensDomain}`; }); afterAll(async () => { diff --git a/packages/templates/api/assemblyscript/src/__tests__/utils.ts b/packages/templates/api/assemblyscript/src/__tests__/utils.ts index fb38fcf922..661a685e12 100644 --- a/packages/templates/api/assemblyscript/src/__tests__/utils.ts +++ b/packages/templates/api/assemblyscript/src/__tests__/utils.ts @@ -55,10 +55,3 @@ export async function getProviders(): Promise { const clientConfig = getPlugins(ethereum, ipfs, data.ensAddress); return { ipfs, ethereum, ensAddress: data.ensAddress, clientConfig }; } - -export async function getEnsUri(): Promise { - const { ensAddress, ipfs } = await getProviders(); - const apiPath: string = path.resolve(__dirname + "/../../"); - const api = await buildAndDeployApi(apiPath, ipfs, ensAddress); - return `ens/testnet/${api.ensDomain}`; -} From 27f5d24b51da97503ed8544ad342a75161a149c1 Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 20 Apr 2022 18:31:24 +0200 Subject: [PATCH 27/41] (chore): updated buildAndDeployApi usages to web3apiclient tests --- .../src/__tests__/Web3ApiClient.spec.ts | 438 ++++++++++++------ .../client/src/__tests__/resolveUri.spec.ts | 4 +- 2 files changed, 288 insertions(+), 154 deletions(-) diff --git a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts index addb07de8e..c95bd891ba 100644 --- a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts +++ b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts @@ -31,12 +31,16 @@ describe("Web3ApiClient", () => { let ipfsProvider: string; let ethProvider: string; let ensAddress: string; + let ensRegistrarAddress: string; + let ensResolverAddress: string; beforeAll(async () => { - const { ipfs, ethereum, ensAddress: ens } = await initTestEnvironment(); + const { ipfs, ethereum, ensAddress: ens, registrarAddress, resolverAddress } = await initTestEnvironment(); ipfsProvider = ipfs; ethProvider = ethereum; ensAddress = ens; + ensRegistrarAddress = registrarAddress; + ensResolverAddress = resolverAddress; }); afterAll(async () => { @@ -186,15 +190,20 @@ describe("Web3ApiClient", () => { }); it("invoke with decode false/true works as expected", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, + const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-storage`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; - const client = await getClient(); - + // The decode option is defaulted to true { const result = await client.invoke({ @@ -250,11 +259,24 @@ describe("Web3ApiClient", () => { }); it("invoke simple-storage with custom redirects", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, + const client = await getClient({ + plugins: [ + { + uri: "w3://ens/mock.web3api.eth", + plugin: mockPlugin(), + }, + ], + }); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-storage`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -265,15 +287,6 @@ describe("Web3ApiClient", () => { }, ]; - const client = await getClient({ - plugins: [ - { - uri: "w3://ens/mock.web3api.eth", - plugin: mockPlugin(), - }, - ], - }); - const result = await client.invoke({ uri: ensUri, module: "mutation", @@ -289,11 +302,24 @@ describe("Web3ApiClient", () => { }); it("simple-storage with query time redirects", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, + const client = await getClient({ + plugins: [ + { + uri: "w3://ens/mock.web3api.eth", + plugin: mockPlugin(), + }, + ], + }); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-storage`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -304,15 +330,6 @@ describe("Web3ApiClient", () => { }, ]; - const client = await getClient({ - plugins: [ - { - uri: "w3://ens/mock.web3api.eth", - plugin: mockPlugin(), - }, - ], - }); - const deploy = await client.query<{ deployContract: string; }>({ @@ -709,13 +726,17 @@ describe("Web3ApiClient", () => { }); it("asyncify", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/asyncify`, - ipfsProvider, - ensAddress - ); - const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/asyncify`, + ipfsProvider, + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; const ipfsUri = `ipfs/${api.ipfsCid}`; @@ -949,13 +970,17 @@ describe("Web3ApiClient", () => { }); it("simple-storage", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, - ipfsProvider, - ensAddress - ); - const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-storage`, + ipfsProvider, + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; const ipfsUri = `ipfs/${api.ipfsCid}`; @@ -1125,15 +1150,19 @@ describe("Web3ApiClient", () => { }); it("object-types", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/object-types`, + const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/object-types`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; - const client = await getClient(); - const method1a = await client.query<{ method1: { prop: string; @@ -1357,15 +1386,19 @@ describe("Web3ApiClient", () => { }); it("bigint-type", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/bigint-type`, + const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/bigint-type`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; - const client = await getClient(); - { const response = await client.query<{ method: string; @@ -1425,13 +1458,18 @@ describe("Web3ApiClient", () => { it("JSON-type", async () => { type Json = string; - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/json-type`, + const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/json-type`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; - const client = await getClient(); const value = { foo: "bar", bar: "baz" }; const parseResponse = await client.query<{ @@ -1508,15 +1546,19 @@ describe("Web3ApiClient", () => { }); it("bytes-type", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/bytes-type`, + const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/bytes-type`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; - const client = await getClient(); - const response = await client.query<{ bytesMethod: Buffer; }>({ @@ -1543,15 +1585,19 @@ describe("Web3ApiClient", () => { }); it("enum-types", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/enum-types`, + const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/enum-types`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; - const client = await getClient(); - const method1a = await client.query({ uri: ensUri, query: ` @@ -1623,14 +1669,18 @@ describe("Web3ApiClient", () => { }); it("should work with large types", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/large-types`, - ipfsProvider, - ensAddress - ); - const ensUri = `ens/testnet/${api.ensDomain}`; const client = await getClient(); + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/large-types`, + ipfsProvider, + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); + const ensUri = `ens/testnet/${api.ensDomain}`; const largeStr = new Array(10000).join("web3api "); const largeBytes = new Uint8Array(Buffer.from(largeStr)); const largeStrArray = []; @@ -1675,13 +1725,18 @@ describe("Web3ApiClient", () => { }); it("number-types under and overflows", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/number-types`, + const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/number-types`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; - const client = await getClient(); const i8Underflow = await client.query<{ i8Method: number; @@ -1823,13 +1878,18 @@ describe("Web3ApiClient", () => { }); it("invalid type errors", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/invalid-types`, + const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/invalid-types`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; - const client = await getClient(); const invalidBoolIntSent = await client.query({ uri: ensUri, @@ -1966,11 +2026,17 @@ describe("Web3ApiClient", () => { }); it("env types", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/env-types`, + const deployClient = await getClient() + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/env-types`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client: deployClient + }); const ensUri = `ens/testnet/${api.ensDomain}`; const client = await getClient({ @@ -2058,11 +2124,17 @@ describe("Web3ApiClient", () => { }); it("query time env types", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/env-types`, + const deployClient = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/env-types`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client: deployClient + }); const ensUri = `ens/testnet/${api.ensDomain}`; const client = await getClient({ @@ -2174,11 +2246,17 @@ describe("Web3ApiClient", () => { }); it("env client types", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/env-client-types`, + const deployClient = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/env-client-types`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client: deployClient + }); const ensUri = `ens/testnet/${api.ensDomain}`; const client = await getClient({ @@ -2303,18 +2381,28 @@ describe("Web3ApiClient", () => { }); it("e2e interface implementations", async () => { - let interfaceApi = await buildAndDeployApi( - `${GetPathToTestApis()}/implementations/test-interface`, + const deployClient = await getClient(); + + let interfaceApi = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/implementations/test-interface`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client: deployClient + }); const interfaceUri = `w3://ens/testnet/${interfaceApi.ensDomain}`; - const implementationApi = await buildAndDeployApi( - `${GetPathToTestApis()}/implementations/test-api`, + const implementationApi = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/implementations/test-api`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client: deployClient + }); const implementationUri = `w3://ens/testnet/${implementationApi.ensDomain}`; const client = await getClient({ @@ -2393,12 +2481,18 @@ describe("Web3ApiClient", () => { }); it("getManifest -- web3api manifest, build manifest, meta manifest", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, - ipfsProvider, - ensAddress - ); const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-storage`, + ipfsProvider, + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); + const ensUri = `ens/testnet/${api.ensDomain}`; const actualManifestStr: string = readFileSync( @@ -2528,12 +2622,17 @@ enum Logger_LogLevel @imported( }); it("getFile -- simple-storage web3api", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, - ipfsProvider, - ensAddress - ); const client = await getClient(); + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-storage`, + ipfsProvider, + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); + const ensUri = `ens/testnet/${api.ensDomain}`; const manifest: Web3ApiManifest = await client.getManifest(ensUri, { @@ -2576,12 +2675,18 @@ enum Logger_LogLevel @imported( }); it("simple-storage: subscribe", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, - ipfsProvider, - ensAddress - ); const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-storage`, + ipfsProvider, + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); + const ensUri = `ens/testnet/${api.ensDomain}`; const ipfsUri = `ipfs/${api.ipfsCid}`; @@ -2671,12 +2776,17 @@ enum Logger_LogLevel @imported( }); it("simple-storage: subscription early stop", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, - ipfsProvider, - ensAddress - ); const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-storage`, + ipfsProvider, + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; const ipfsUri = `ipfs/${api.ipfsCid}`; @@ -2771,15 +2881,19 @@ enum Logger_LogLevel @imported( }); it("queries API schemas that use reserved keywords", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/reserved-words`, + const client = await getClient(); + + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/reserved-words`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; - const client = await getClient(); - const query = await client.query<{ method1: { const: string; @@ -2808,12 +2922,17 @@ enum Logger_LogLevel @imported( it("e2e getImplementations capability", async () => { const interfaceUri = "w3://ens/interface.eth"; + const deployClient = await getClient(); - const implementationApi = await buildAndDeployApi( - `${GetPathToTestApis()}/implementations/test-use-getImpl`, + const implementationApi = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/implementations/test-use-getImpl`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client: deployClient + }); const implementationUri = `w3://ens/testnet/${implementationApi.ensDomain}`; const client = await getClient({ @@ -2851,17 +2970,22 @@ enum Logger_LogLevel @imported( it("e2e Interface invoke method", async () => { const interfaceUri = "w3://ens/interface.eth"; + const deployClient = await getClient(); // Build interface polywrapper await runCLI({ args: ["build"], cwd: `${GetPathToTestApis()}/interface-invoke/test-interface`, }); - const implementationApi = await buildAndDeployApi( - `${GetPathToTestApis()}/interface-invoke/test-implementation`, + const implementationApi = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/interface-invoke/test-implementation`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client: deployClient + }); const implementationUri = `w3://ens/testnet/${implementationApi.ensDomain}`; const client = await getClient({ @@ -2873,11 +2997,15 @@ enum Logger_LogLevel @imported( ], }); - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/interface-invoke/test-api`, + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/interface-invoke/test-api`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const apiUri = `w3://ens/testnet/${api.ensDomain}`; const query = await client.query<{ @@ -2918,13 +3046,17 @@ enum Logger_LogLevel @imported( }); it("Map-type", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/map-type`, + const client = await getClient(); + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/map-type`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client + }); const ensUri = `ens/testnet/${api.ensDomain}`; - const client = await getClient(); const mapClass = new Map().set("Hello", 1).set("Heyo", 50); const mapRecord: Record = { diff --git a/packages/js/client/src/__tests__/resolveUri.spec.ts b/packages/js/client/src/__tests__/resolveUri.spec.ts index 6dff764019..50ab7351e0 100644 --- a/packages/js/client/src/__tests__/resolveUri.spec.ts +++ b/packages/js/client/src/__tests__/resolveUri.spec.ts @@ -24,10 +24,12 @@ describe("Web3ApiClient - resolveUri", () => { let ensResolverAddress: string; beforeAll(async () => { - const { ipfs, ethereum, ensAddress: ens } = await initTestEnvironment(); + const { ipfs, ethereum, ensAddress: ens, registrarAddress, resolverAddress } = await initTestEnvironment(); ipfsProvider = ipfs; ethProvider = ethereum; ensAddress = ens; + ensRegistrarAddress = registrarAddress; + ensResolverAddress = resolverAddress; }); afterAll(async () => { From d275d97a8f3001bc403fba3d0135b797f3cefe59 Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 20 Apr 2022 18:41:59 +0200 Subject: [PATCH 28/41] (fix): tweaked URI/CID parsing --- packages/cli/src/lib/deployers/ens/index.ts | 2 +- packages/cli/src/lib/deployers/ipfs/index.ts | 2 +- packages/js/test-env/src/index.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/lib/deployers/ens/index.ts b/packages/cli/src/lib/deployers/ens/index.ts index 74114efd2b..23c60c5b65 100644 --- a/packages/cli/src/lib/deployers/ens/index.ts +++ b/packages/cli/src/lib/deployers/ens/index.ts @@ -68,7 +68,7 @@ class ENSPublisher implements Deployer { await tx.wait(); - return new Uri(`w3://ens/${config.domainName}`); + return new Uri(`ens/${config.domainName}`); } } diff --git a/packages/cli/src/lib/deployers/ipfs/index.ts b/packages/cli/src/lib/deployers/ipfs/index.ts index 6c1a8981fd..0a5d9ad6ff 100644 --- a/packages/cli/src/lib/deployers/ipfs/index.ts +++ b/packages/cli/src/lib/deployers/ipfs/index.ts @@ -40,7 +40,7 @@ class IPFSDeployer implements Deployer { } } - return new Uri(`w3://ipfs/${rootCID}`); + return new Uri(`ipfs/${rootCID}`); } } diff --git a/packages/js/test-env/src/index.ts b/packages/js/test-env/src/index.ts index 15eecd9352..d69684f123 100644 --- a/packages/js/test-env/src/index.ts +++ b/packages/js/test-env/src/index.ts @@ -4,7 +4,7 @@ import axios from "axios"; import fs from "fs"; import { ethers } from "ethers"; import yaml from "js-yaml"; -import { Client, deserializeWeb3ApiManifest } from "@web3api/core-js"; +import { Client, deserializeWeb3ApiManifest, Uri } from "@web3api/core-js"; interface TestEnvironment { ipfs: string; @@ -314,7 +314,7 @@ export async function buildAndDeployApi({ throw Error(`W3 CLI output missing IPFS CID.\nOutput: ${deployStdout}`); } - const apiCid = result[1]; + const apiCid = new Uri(result[1]).path; return { ensDomain: apiEns, From 8b70cd5d33c8bfb523133f80f524b11ba4afebf7 Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 20 Apr 2022 19:21:07 +0200 Subject: [PATCH 29/41] (chore): resolving ENS wrapper from rinkeby, instead of filesystem --- .../ethereum/src/__tests__/e2e.spec.ts | 4 +- .../js/test-env/ens-wrapper/mutation.wasm | Bin 213422 -> 0 bytes packages/js/test-env/ens-wrapper/query.wasm | Bin 92884 -> 0 bytes .../js/test-env/ens-wrapper/schema.graphql | 709 ------------------ .../test-env/ens-wrapper/web3api.build.json | 6 - packages/js/test-env/ens-wrapper/web3api.json | 16 - packages/js/test-env/package.json | 6 +- packages/js/test-env/src/index.ts | 5 +- 8 files changed, 6 insertions(+), 740 deletions(-) delete mode 100644 packages/js/test-env/ens-wrapper/mutation.wasm delete mode 100644 packages/js/test-env/ens-wrapper/query.wasm delete mode 100644 packages/js/test-env/ens-wrapper/schema.graphql delete mode 100644 packages/js/test-env/ens-wrapper/web3api.build.json delete mode 100644 packages/js/test-env/ens-wrapper/web3api.json diff --git a/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts b/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts index 8b95e7c8a4..7d38a32462 100644 --- a/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts +++ b/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts @@ -94,8 +94,8 @@ describe("Ethereum Plugin", () => { await stopTestEnvironment(); }); - describe.only("Query", () => { - it.only("callContractView", async () => { + describe("Query", () => { + it("callContractView", async () => { const node = namehash("whatever.eth") const response = await client.query<{ callContractView: string }>({ uri, diff --git a/packages/js/test-env/ens-wrapper/mutation.wasm b/packages/js/test-env/ens-wrapper/mutation.wasm deleted file mode 100644 index df308c48b57689c68c6aa7219eb6947aa0185a39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 213422 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 diff --git a/packages/js/test-env/ens-wrapper/query.wasm b/packages/js/test-env/ens-wrapper/query.wasm deleted file mode 100644 index 6d61eac356922eca019523d7b920717b31b3bc7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92884 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 KqZw5x|NjHraauwE diff --git a/packages/js/test-env/ens-wrapper/schema.graphql b/packages/js/test-env/ens-wrapper/schema.graphql deleted file mode 100644 index 84d0bb99d9..0000000000 --- a/packages/js/test-env/ens-wrapper/schema.graphql +++ /dev/null @@ -1,709 +0,0 @@ -### Web3API Header START ### -scalar UInt -scalar UInt8 -scalar UInt16 -scalar UInt32 -scalar Int -scalar Int8 -scalar Int16 -scalar Int32 -scalar Bytes -scalar BigInt -scalar JSON -scalar Map - -directive @imported( - uri: String! - namespace: String! - nativeType: String! -) on OBJECT | ENUM - -directive @imports( - types: [String!]! -) on OBJECT - -directive @capability( - type: String! - uri: String! - namespace: String! -) repeatable on OBJECT - -directive @enabled_interface on OBJECT - -directive @annotate(type: String!) on FIELD - -### Web3API Header END ### - -type Query @imports( - types: [ - "Ethereum_Query", - "Ethereum_Connection", - "Ethereum_TxOverrides", - "Ethereum_StaticTxResult", - "Ethereum_TxRequest", - "Ethereum_TxReceipt", - "Ethereum_Log", - "Ethereum_EventNotification", - "Ethereum_Network", - "UTS46_Query", - "UTS46_ConvertResult", - "SHA3_Query" - ] -) { - getResolver( - registryAddress: String! - domain: String! - connection: Ethereum_Connection - ): String! - - getOwner( - domain: String! - registryAddress: String! - connection: Ethereum_Connection - ): String! - - getAddress( - domain: String! - resolverAddress: String! - connection: Ethereum_Connection - ): String! - - getAddressFromDomain( - domain: String! - registryAddress: String! - connection: Ethereum_Connection - ): String! - - getContentHash( - domain: String! - resolverAddress: String! - connection: Ethereum_Connection - ): String! - - getContentHashFromDomain( - domain: String! - registryAddress: String! - connection: Ethereum_Connection - ): String! - - getExpiryTimes( - domain: String! - registrarAddress: String! - connection: Ethereum_Connection - ): String! - - getReverseResolver( - address: String! - registryAddress: String! - connection: Ethereum_Connection - ): String! - - getNameFromReverseResolver( - address: String! - resolverAddress: String! - connection: Ethereum_Connection - ): String! - - getNameFromAddress( - address: String! - registryAddress: String! - connection: Ethereum_Connection - ): String! - - getTextRecord( - domain: String! - resolverAddress: String! - key: String! - connection: Ethereum_Connection - ): String! -} - -type Mutation @imports( - types: [ - "Ethereum_Mutation", - "Ethereum_Connection", - "Ethereum_TxOverrides", - "Ethereum_TxResponse", - "Ethereum_Access", - "Ethereum_TxReceipt", - "Ethereum_Log", - "Ethereum_TxRequest", - "UTS46_Query", - "UTS46_ConvertResult", - "SHA3_Query" - ] -) { - setResolver( - domain: String! - resolverAddress: String! - registryAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - registerDomain( - domain: String! - registrarAddress: String! - registryAddress: String! - owner: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - reverseRegisterDomain( - domain: String! - reverseRegistryAddress: String! - owner: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - setName( - domain: String! - reverseRegistryAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - setAddress( - domain: String! - address: String! - resolverAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - setOwner( - domain: String! - newOwner: String! - registryAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - setSubdomainOwner( - subdomain: String! - owner: String! - registryAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - setRecord( - domain: String! - owner: String! - resolverAddress: String! - ttl: String! - registryAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - setSubdomainRecord( - domain: String! - label: String! - owner: String! - resolverAddress: String! - ttl: String! - registryAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - setContentHash( - domain: String! - cid: String! - resolverAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - setAddressFromDomain( - domain: String! - address: String! - registryAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - setContentHashFromDomain( - domain: String! - cid: String! - registryAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - deployFIFSRegistrar( - registryAddress: String! - tld: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): String! - - registerSubnodeOwnerWithFIFSRegistrar( - label: String! - owner: String! - fifsRegistrarAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - setTextRecord( - domain: String! - resolverAddress: String! - key: String! - value: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): Ethereum_TxResponse! - - configureOpenDomain( - tld: String! - owner: String! - registryAddress: String! - resolverAddress: String! - registrarAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): ConfigureOpenDomainResponse! - - createSubdomainInOpenDomain( - label: String! - domain: String! - owner: String! - fifsRegistrarAddress: String! - registryAddress: String! - resolverAddress: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): CreateSubdomainInOpenDomainResponse! - - createSubdomainInOpenDomainAndSetContentHash( - label: String! - domain: String! - owner: String! - fifsRegistrarAddress: String! - registryAddress: String! - resolverAddress: String! - cid: String! - connection: Ethereum_Connection - txOverrides: TxOverrides - ): CreateSubdomainInOpenDomainAndSetContentHashResponse -} - -type ConfigureOpenDomainResponse { - fifsRegistrarAddress: String! - registerOpenDomainTxReceipt: Ethereum_TxResponse! - setSubdomainRecordTxReceipt: Ethereum_TxResponse! -} - -type CreateSubdomainInOpenDomainResponse { - registerSubdomainTxReceipt: Ethereum_TxResponse! - setResolverTxReceipt: Ethereum_TxResponse! -} - -type CreateSubdomainInOpenDomainAndSetContentHashResponse implements CreateSubdomainInOpenDomainResponse { - setContentHashReceiptTx: Ethereum_TxResponse! - registerSubdomainTxReceipt: Ethereum_TxResponse! - setResolverTxReceipt: Ethereum_TxResponse! -} - -type TxOverrides { - gasPrice: BigInt - gasLimit: BigInt -} - -### Imported Queries START ### - -type Ethereum_Query @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "Query" -) { - callContractView( - address: String! - method: String! - args: [String!] - connection: Ethereum_Connection - ): String! - - callContractStatic( - address: String! - method: String! - args: [String!] - connection: Ethereum_Connection - txOverrides: Ethereum_TxOverrides - ): Ethereum_StaticTxResult! - - getBalance( - address: String! - blockTag: BigInt - connection: Ethereum_Connection - ): BigInt! - - encodeParams( - types: [String!]! - values: [String!]! - ): String! - - encodeFunction( - method: String! - args: [String!] - ): String! - - solidityPack( - types: [String!]! - values: [String!]! - ): String! - - solidityKeccak256( - types: [String!]! - values: [String!]! - ): String! - - soliditySha256( - types: [String!]! - values: [String!]! - ): String! - - getSignerAddress( - connection: Ethereum_Connection - ): String! - - getSignerBalance( - blockTag: BigInt - connection: Ethereum_Connection - ): BigInt! - - getSignerTransactionCount( - blockTag: BigInt - connection: Ethereum_Connection - ): BigInt! - - getGasPrice( - connection: Ethereum_Connection - ): BigInt! - - estimateTransactionGas( - tx: Ethereum_TxRequest! - connection: Ethereum_Connection - ): BigInt! - - estimateContractCallGas( - address: String! - method: String! - args: [String!] - connection: Ethereum_Connection - txOverrides: Ethereum_TxOverrides - ): BigInt! - - checkAddress( - address: String! - ): Boolean! - - toWei( - eth: String! - ): BigInt! - - toEth( - wei: BigInt! - ): String! - - awaitTransaction( - txHash: String! - confirmations: UInt32! - timeout: UInt32! - connection: Ethereum_Connection - ): Ethereum_TxReceipt! - - waitForEvent( - address: String! - event: String! - args: [String!] - timeout: UInt32 - connection: Ethereum_Connection - ): Ethereum_EventNotification! - - getNetwork( - connection: Ethereum_Connection - ): Ethereum_Network! -} - -type UTS46_Query @imported( - uri: "w3://ens/uts46.web3api.eth", - namespace: "UTS46", - nativeType: "Query" -) { - toAscii( - value: String! - ): String! - - toUnicode( - value: String! - ): String! - - convert( - value: String! - ): UTS46_ConvertResult! -} - -type SHA3_Query @imported( - uri: "w3://ens/sha3.web3api.eth", - namespace: "SHA3", - nativeType: "Query" -) { - sha3_512( - message: String! - ): String! - - sha3_384( - message: String! - ): String! - - sha3_256( - message: String! - ): String! - - sha3_224( - message: String! - ): String! - - keccak_512( - message: String! - ): String! - - keccak_384( - message: String! - ): String! - - keccak_256( - message: String! - ): String! - - keccak_224( - message: String! - ): String! - - hex_keccak_256( - message: String! - ): String! - - buffer_keccak_256( - message: Bytes! - ): String! - - shake_128( - message: String! - outputBits: Int! - ): String! - - shake_256( - message: String! - outputBits: Int! - ): String! -} - -type Ethereum_Mutation @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "Mutation" -) { - callContractMethod( - address: String! - method: String! - args: [String!] - connection: Ethereum_Connection - txOverrides: Ethereum_TxOverrides - ): Ethereum_TxResponse! - - callContractMethodAndWait( - address: String! - method: String! - args: [String!] - connection: Ethereum_Connection - txOverrides: Ethereum_TxOverrides - ): Ethereum_TxReceipt! - - sendTransaction( - tx: Ethereum_TxRequest! - connection: Ethereum_Connection - ): Ethereum_TxResponse! - - sendTransactionAndWait( - tx: Ethereum_TxRequest! - connection: Ethereum_Connection - ): Ethereum_TxReceipt! - - deployContract( - abi: String! - bytecode: String! - args: [String!] - connection: Ethereum_Connection - ): String! - - signMessage( - message: String! - connection: Ethereum_Connection - ): String! - - sendRPC( - method: String! - params: [String!]! - connection: Ethereum_Connection - ): String -} - -### Imported Queries END ### - -### Imported Objects START ### - -type Ethereum_Connection @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "Connection" -) { - node: String - networkNameOrChainId: String -} - -type Ethereum_TxOverrides @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "TxOverrides" -) { - gasLimit: BigInt - gasPrice: BigInt - value: BigInt -} - -type Ethereum_StaticTxResult @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "StaticTxResult" -) { - result: String! - error: Boolean! -} - -type Ethereum_TxRequest @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "TxRequest" -) { - to: String - from: String - nonce: UInt32 - gasLimit: BigInt - gasPrice: BigInt - data: String - value: BigInt - chainId: BigInt - type: UInt32 -} - -type Ethereum_TxReceipt @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "TxReceipt" -) { - to: String! - from: String! - contractAddress: String! - transactionIndex: UInt32! - root: String - gasUsed: BigInt! - logsBloom: String! - transactionHash: String! - logs: [Ethereum_Log!]! - blockNumber: BigInt! - blockHash: String! - confirmations: UInt32! - cumulativeGasUsed: BigInt! - effectiveGasPrice: BigInt! - byzantium: Boolean! - type: UInt32! - status: UInt32 -} - -type Ethereum_Log @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "Log" -) { - blockNumber: BigInt! - blockHash: String! - transactionIndex: UInt32! - removed: Boolean! - address: String! - data: String! - topics: [String!]! - transactionHash: String! - logIndex: UInt32! -} - -type Ethereum_EventNotification @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "EventNotification" -) { - data: String! - address: String! - log: Ethereum_Log! -} - -type Ethereum_Network @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "Network" -) { - name: String! - chainId: BigInt! - ensAddress: String -} - -type UTS46_ConvertResult @imported( - uri: "w3://ens/uts46.web3api.eth", - namespace: "UTS46", - nativeType: "ConvertResult" -) { - IDN: String! - PC: String! -} - -type Ethereum_TxResponse @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "TxResponse" -) { - hash: String! - to: String - from: String! - nonce: UInt32! - gasLimit: BigInt! - gasPrice: BigInt - data: String! - value: BigInt! - chainId: BigInt! - blockNumber: BigInt - blockHash: String - timestamp: UInt32 - confirmations: UInt32! - raw: String - r: String - s: String - v: UInt32 - type: UInt32 - accessList: [Ethereum_Access!] -} - -type Ethereum_Access @imported( - uri: "w3://ens/ethereum.web3api.eth", - namespace: "Ethereum", - nativeType: "Access" -) { - address: String! - storageKeys: [String!]! -} - -### Imported Objects END ### diff --git a/packages/js/test-env/ens-wrapper/web3api.build.json b/packages/js/test-env/ens-wrapper/web3api.build.json deleted file mode 100644 index f19dc23c6c..0000000000 --- a/packages/js/test-env/ens-wrapper/web3api.build.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "format": "0.0.1-prealpha.2", - "docker": { - "buildImageId": "sha256:b2b93ec62f13faae089d7bb52b0140948e00da52bf55e1cdb589826946ec92be\n" - } -} \ No newline at end of file diff --git a/packages/js/test-env/ens-wrapper/web3api.json b/packages/js/test-env/ens-wrapper/web3api.json deleted file mode 100644 index 10919ef155..0000000000 --- a/packages/js/test-env/ens-wrapper/web3api.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "format": "0.0.1-prealpha.7", - "language": "wasm/assemblyscript", - "build": "./web3api.build.json", - "modules": { - "mutation": { - "module": "./mutation.wasm", - "schema": "./schema.graphql" - }, - "query": { - "module": "./query.wasm", - "schema": "./schema.graphql" - } - }, - "name": "Unnamed" -} \ No newline at end of file diff --git a/packages/js/test-env/package.json b/packages/js/test-env/package.json index d08f996c8d..76e062cff6 100644 --- a/packages/js/test-env/package.json +++ b/packages/js/test-env/package.json @@ -12,8 +12,7 @@ "build" ], "scripts": { - "build": "rimraf ./build && tsc --project tsconfig.build.json && yarn build:enswrapper", - "build:enswrapper": "copyfiles ./ens-wrapper/* ./build/ens-wrapper -u 1", + "build": "rimraf ./build && tsc --project tsconfig.build.json", "lint": "eslint --color -c ../../../.eslintrc.js src/" }, "dependencies": { @@ -26,8 +25,7 @@ "devDependencies": { "rimraf": "3.0.2", "ts-node": "8.10.2", - "typescript": "4.0.7", - "copyfiles": "2.4.1" + "typescript": "4.0.7" }, "gitHead": "7346adaf5adb7e6bbb70d9247583e995650d390a", "publishConfig": { diff --git a/packages/js/test-env/src/index.ts b/packages/js/test-env/src/index.ts index d69684f123..79681073ef 100644 --- a/packages/js/test-env/src/index.ts +++ b/packages/js/test-env/src/index.ts @@ -17,7 +17,6 @@ interface TestEnvironment { const monorepoCli = `${__dirname}/../../../cli/bin/w3`; const npmCli = `${__dirname}/../../cli/bin/w3`; -const ensWrapperPath = `${__dirname}/ens-wrapper`; export const initTestEnvironment = async ( cli?: string @@ -190,7 +189,7 @@ export async function buildAndDeployApi({ // TODO: deploy ENS wrapper to testenv const { error: registerError } = await client.invoke({ - uri: `fs/${ensWrapperPath}`, + uri: `w3://ens/rinkeby/ens.web3api.eth`, module: "mutation", method: "registerDomain", input: { @@ -211,7 +210,7 @@ export async function buildAndDeployApi({ } const { error: setResolverError } = await client.invoke({ - uri: `fs/${ensWrapperPath}`, + uri: `w3://ens/rinkeby/ens.web3api.eth`, module: "mutation", method: "setResolver", input: { From 547795e267bd80b6fba04e4b1176b4a703ebebb1 Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 20 Apr 2022 21:52:55 +0200 Subject: [PATCH 30/41] (fix): fixed CLI tests --- packages/cli/lang/en.json | 1 + packages/cli/lang/es.json | 1 + packages/cli/src/__tests__/e2e/build.spec.ts | 34 -------- packages/cli/src/__tests__/e2e/deploy.spec.ts | 4 +- packages/cli/src/__tests__/e2e/help.spec.ts | 19 +++-- packages/cli/src/__tests__/e2e/query.spec.ts | 46 +++++----- .../__tests__/project/recipes/constants.json | 2 +- .../__tests__/project/recipes/constants.yaml | 2 +- packages/cli/src/commands/deploy.ts | 2 +- packages/js/test-env/src/index.ts | 84 ++++++++----------- 10 files changed, 80 insertions(+), 115 deletions(-) diff --git a/packages/cli/lang/en.json b/packages/cli/lang/en.json index 8c56436a1d..601487ecee 100644 --- a/packages/cli/lang/en.json +++ b/packages/cli/lang/en.json @@ -14,6 +14,7 @@ "commands_build_options_w": "Automatically rebuild when changes are made (default: false)", "commands_build_options_v": "Verbose output (default: false)", "commands_build_uriViewers": "URI Viewers", + "commands_deploy_description": "Deploys/Publishes a Web3API", "commands_deploy_options_options": "options", "commands_deploy_options_o_path": "path", "commands_deploy_options_o_string": "string", diff --git a/packages/cli/lang/es.json b/packages/cli/lang/es.json index c1f2dd676e..5b1a4a5611 100644 --- a/packages/cli/lang/es.json +++ b/packages/cli/lang/es.json @@ -15,6 +15,7 @@ "commands_build_options_w": "Automatically rebuild when changes are made (default: false)", "commands_build_options_v": "Verbose output (default: false)", "commands_build_uriViewers": "URI Viewers", + "commands_deploy_description": "Deploys/Publishes a Web3API", "commands_deploy_options_options": "options", "commands_deploy_options_o_path": "path", "commands_deploy_options_o_string": "string", diff --git a/packages/cli/src/__tests__/e2e/build.spec.ts b/packages/cli/src/__tests__/e2e/build.spec.ts index 7805cce82c..de45733621 100644 --- a/packages/cli/src/__tests__/e2e/build.spec.ts +++ b/packages/cli/src/__tests__/e2e/build.spec.ts @@ -11,9 +11,7 @@ w3 build [options] Options: -h, --help Show usage information -m, --manifest-file Path to the Web3API Build manifest file (default: web3api.yaml | web3api.yml) - -i, --ipfs [] Upload build results to an IPFS node (default: dev-server's node) -o, --output-dir Output directory for build results (default: build/) - -e, --test-ens <[address,]domain> Publish the package to a test ENS domain locally (requires --ipfs) -w, --watch Automatically rebuild when changes are made (default: false) -v, --verbose Verbose output (default: false) @@ -52,38 +50,6 @@ describe("e2e tests for build command", () => { ${HELP}`); }); - test("Should throw error for invalid params - testEns", async () => { - const { exitCode: code, stdout: output, stderr: error } = await runCLI( - { - args: ["build", "--test-ens"], - cwd: projectRoot, - cli: w3Cli, - }, - ); - - expect(code).toEqual(1); - expect(error).toBe(""); - expect(clearStyle(output)) - .toEqual(`--test-ens option missing <[address,]domain> argument -${HELP}`); - }); - - test("Should throw error for invalid params - ipfs", async () => { - const { exitCode: code, stdout: output, stderr: error } = await runCLI( - { - args: ["build", "--test-ens", "test.eth"], - cwd: projectRoot, - cli: w3Cli, - }, - ); - - expect(code).toEqual(1); - expect(error).toBe(""); - expect(clearStyle(output)) - .toEqual(`--test-ens option requires the --ipfs [] option -${HELP}`); - }); - test("Should throw error for invalid web3api - invalid route", async () => { const { exitCode: code, stdout: output, stderr: error } = await runCLI( { diff --git a/packages/cli/src/__tests__/e2e/deploy.spec.ts b/packages/cli/src/__tests__/e2e/deploy.spec.ts index 755fbc335c..6172d75a1f 100644 --- a/packages/cli/src/__tests__/e2e/deploy.spec.ts +++ b/packages/cli/src/__tests__/e2e/deploy.spec.ts @@ -36,7 +36,7 @@ const setup = async (domainNames: string[]) => { const signer = new Wallet("0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"); // TODO: use the "loadDeployManifest" function - const deployManifest = await loadDeployManifest(`${projectRoot}/web3api.deploy.yaml`); + const { __type, ...deployManifest } = await loadDeployManifest(`${projectRoot}/web3api.deploy.yaml`); Object.entries(deployManifest.stages).forEach(([key, value]) => { if (value.config && value.config.ensRegistryAddress) { @@ -134,7 +134,7 @@ describe("e2e tests for deploy command", () => { }); test("Successfully deploys the project", async () => { - const { exitCode: code, stdout: output } = await runCLI( + const { exitCode: code, stdout: output, stderr } = await runCLI( { args: ["deploy"], cwd: projectRoot, diff --git a/packages/cli/src/__tests__/e2e/help.spec.ts b/packages/cli/src/__tests__/e2e/help.spec.ts index 5aab2a21cb..6db92f9bf5 100644 --- a/packages/cli/src/__tests__/e2e/help.spec.ts +++ b/packages/cli/src/__tests__/e2e/help.spec.ts @@ -4,15 +4,16 @@ import { clearStyle, w3Cli } from "./utils"; import { runCLI } from "@web3api/test-env-js"; const HELP = ` - w3 🔥 Web3API CLI 🔥 - help (h) - - test-env (t) Manage a test environment for Web3API - query (q) Query Web3APIs using recipe scripts - plugin (p) Build/generate types for the plugin - create (c) Create a new project with w3 CLI - codegen (g) Auto-generate API Types - build (b) Builds a Web3API and (optionally) uploads it to IPFS - app (a) Build/generate types for your app + w3 🔥 Web3API CLI 🔥 + help (h) - + test-env (t) Manage a test environment for Web3API + query (q) Query Web3APIs using recipe scripts + plugin (p) Build/generate types for the plugin + deploy (b) Deploys/Publishes a Web3API + create (c) Create a new project with w3 CLI + codegen (g) Auto-generate API Types + build (b) Builds a Web3API + app (a) Build/generate types for your app `; describe("e2e tests for no help", () => { diff --git a/packages/cli/src/__tests__/e2e/query.spec.ts b/packages/cli/src/__tests__/e2e/query.spec.ts index 016d3a803f..d874adde1c 100644 --- a/packages/cli/src/__tests__/e2e/query.spec.ts +++ b/packages/cli/src/__tests__/e2e/query.spec.ts @@ -4,7 +4,7 @@ import yaml from "js-yaml"; import { clearStyle, w3Cli } from "./utils"; -import { runCLI } from "@web3api/test-env-js"; +import { buildAndDeployApi, initTestEnvironment, runCLI } from "@web3api/test-env-js"; import { normalizeLineEndings } from "@web3api/os-js"; import { checkSampleQueryOutput, @@ -12,6 +12,8 @@ import { getSampleOutputWithClientConfig, ISampleOutputOptions, } from "./query.spec.helper"; +import { Web3ApiClient } from "@web3api/client-js"; +import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; const HELP = ` w3 query [options] @@ -58,13 +60,7 @@ ${HELP}`); describe("e2e tests for query command", () => { beforeAll(async () => { - const { exitCode: testenvCode, stderr: testEnvUpErr } = await runCLI({ - args: ["test-env", "up"], - cwd: projectRoot, - cli: w3Cli, - }); - expect(testEnvUpErr).toBe(""); - expect(testenvCode).toEqual(0); + const { ipfs, ethereum, ensAddress: ens, registrarAddress, resolverAddress } = await initTestEnvironment(); const { stderr: deployErr } = await runCLI({ args: ["./deploy-contracts.js"], @@ -74,20 +70,32 @@ describe("e2e tests for query command", () => { expect(deployErr).toBe(""); - const { exitCode: buildCode, stderr: buildErr } = await runCLI({ - args: [ - "build", - "--ipfs", - "http://localhost:5001", - "--test-ens", - "simplestorage.eth", + const client = new Web3ApiClient({ + plugins: [ + { + uri: "w3://ens/ethereum.web3api.eth", + plugin: ethereumPlugin({ + networks: { + testnet: { + provider: ethereum, + } + }, + defaultNetwork: "testnet" + }), + } ], - cwd: projectRoot, - cli: w3Cli, }); - expect(buildErr).toBe(""); - expect(buildCode).toEqual(0); + await buildAndDeployApi({ + apiAbsPath: projectRoot, + ipfsProvider: ipfs, + ethereumProvider: ethereum, + ensRegistrarAddress: registrarAddress, + ensResolverAddress: resolverAddress, + ensRegistryAddress: ens, + ensName: "simplestorage.eth", + client + }) }); afterAll(async () => { diff --git a/packages/cli/src/__tests__/project/recipes/constants.json b/packages/cli/src/__tests__/project/recipes/constants.json index bd46d57bc4..5c7119e4a6 100644 --- a/packages/cli/src/__tests__/project/recipes/constants.json +++ b/packages/cli/src/__tests__/project/recipes/constants.json @@ -1,3 +1,3 @@ { - "SimpleStorageAddr": "0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab" + "SimpleStorageAddr": "0x9b1f7F645351AF3631a656421eD2e40f2802E6c0" } \ No newline at end of file diff --git a/packages/cli/src/__tests__/project/recipes/constants.yaml b/packages/cli/src/__tests__/project/recipes/constants.yaml index c90fc49e44..ea1045f842 100644 --- a/packages/cli/src/__tests__/project/recipes/constants.yaml +++ b/packages/cli/src/__tests__/project/recipes/constants.yaml @@ -1 +1 @@ -SimpleStorageAddr: "0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab" +SimpleStorageAddr: "0x9b1f7F645351AF3631a656421eD2e40f2802E6c0" diff --git a/packages/cli/src/commands/deploy.ts b/packages/cli/src/commands/deploy.ts index 1231a800fd..4b8bac59a2 100644 --- a/packages/cli/src/commands/deploy.ts +++ b/packages/cli/src/commands/deploy.ts @@ -31,7 +31,7 @@ ${optionsStr[0].toUpperCase() + optionsStr.slice(1)}: export default { alias: ["b"], - description: intlMsg.commands_build_description(), + description: intlMsg.commands_deploy_description(), run: async (toolbox: GluegunToolbox): Promise => { const { filesystem, parameters, print } = toolbox; diff --git a/packages/js/test-env/src/index.ts b/packages/js/test-env/src/index.ts index 79681073ef..09ea3c2ecd 100644 --- a/packages/js/test-env/src/index.ts +++ b/packages/js/test-env/src/index.ts @@ -136,6 +136,7 @@ export async function buildAndDeployApi({ ensRegistrarAddress, ensResolverAddress, ethereumProvider, + ensName, client, }: { apiAbsPath: string; @@ -144,6 +145,7 @@ export async function buildAndDeployApi({ ensRegistrarAddress: string; ensResolverAddress: string; ethereumProvider: string; + ensName?: string; client: Client; }): Promise<{ ensDomain: string; @@ -159,7 +161,7 @@ export async function buildAndDeployApi({ ); // create a new ENS domain - const apiEns = `${generateName()}.eth`; + const apiEns = ensName ?? `${generateName()}.eth`; // build API const { @@ -231,51 +233,43 @@ export async function buildAndDeployApi({ // manually configure manifests - const web3apiManifest = deserializeWeb3ApiManifest( + const { __type, ...web3apiManifest } = deserializeWeb3ApiManifest( fs.readFileSync(manifestPath, "utf-8") ); - const useTempManifests = !web3apiManifest.deploy; - - if (useTempManifests) { - fs.writeFileSync( - tempManifestPath, - yaml.dump({ - format: web3apiManifest.format, - name: web3apiManifest.name, - build: web3apiManifest.build, - language: web3apiManifest.language, - modules: web3apiManifest.modules, - deploy: `./${tempDeployManifestFilename}`, - }) - ); + fs.writeFileSync( + tempManifestPath, + yaml.dump({ + ...web3apiManifest, + deploy: `./${tempDeployManifestFilename}`, + }) + ); - fs.writeFileSync( - tempDeployManifestPath, - yaml.dump({ - format: "0.0.1-prealpha.1", - stages: { - ipfsDeploy: { - package: "ipfs", - uri: `fs/${apiAbsPath}/build`, - config: { - gatewayUri: ipfsProvider, - }, + fs.writeFileSync( + tempDeployManifestPath, + yaml.dump({ + format: "0.0.1-prealpha.1", + stages: { + ipfsDeploy: { + package: "ipfs", + uri: `fs/${apiAbsPath}/build`, + config: { + gatewayUri: ipfsProvider, }, - ensPublish: { - package: "ens", - // eslint-disable-next-line @typescript-eslint/naming-convention - depends_on: "ipfsDeploy", - config: { - domainName: apiEns, - provider: ethereumProvider, - ensRegistryAddress, - }, + }, + ensPublish: { + package: "ens", + // eslint-disable-next-line @typescript-eslint/naming-convention + depends_on: "ipfsDeploy", + config: { + domainName: apiEns, + provider: ethereumProvider, + ensRegistryAddress, }, }, - }) - ); - } + }, + }) + ); // deploy API @@ -284,11 +278,7 @@ export async function buildAndDeployApi({ stdout: deployStdout, stderr: deployStderr, } = await runCLI({ - args: [ - "deploy", - "--manifest-file", - useTempManifests ? tempManifestPath : manifestPath, - ], + args: ["deploy", "--manifest-file", tempManifestPath], }); if (deployExitCode !== 0) { @@ -300,10 +290,8 @@ export async function buildAndDeployApi({ // remove manually configured manifests - if (useTempManifests) { - fs.unlinkSync(tempManifestPath); - fs.unlinkSync(tempDeployManifestPath); - } + fs.unlinkSync(tempManifestPath); + fs.unlinkSync(tempDeployManifestPath); // get the IPFS CID of the published package const extractCID = /(w3:\/\/ipfs\/[A-Za-z0-9]+)/; From d08efd084d669793d60a709dcfa6b097d9e0d89e Mon Sep 17 00:00:00 2001 From: namesty Date: Wed, 20 Apr 2022 22:58:44 +0200 Subject: [PATCH 31/41] (chore): using ens wrapper for cli deploy tests ens registering --- packages/cli/src/__tests__/e2e/deploy.spec.ts | 64 ++++++++----------- packages/js/test-env/src/index.ts | 1 - 2 files changed, 28 insertions(+), 37 deletions(-) diff --git a/packages/cli/src/__tests__/e2e/deploy.spec.ts b/packages/cli/src/__tests__/e2e/deploy.spec.ts index 6172d75a1f..945153e071 100644 --- a/packages/cli/src/__tests__/e2e/deploy.spec.ts +++ b/packages/cli/src/__tests__/e2e/deploy.spec.ts @@ -8,9 +8,7 @@ import path from "path"; import axios from "axios"; import { Web3ApiClient } from "@web3api/client-js"; import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; -import { keccak256 } from "js-sha3"; import { Wallet } from "ethers"; -import { namehash } from "ethers/lib/utils"; import yaml from "js-yaml"; import fs from "fs"; import { loadDeployManifest } from "../../lib"; @@ -35,7 +33,6 @@ const setup = async (domainNames: string[]) => { const registrarAddress = data.registrarAddress const signer = new Wallet("0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"); - // TODO: use the "loadDeployManifest" function const { __type, ...deployManifest } = await loadDeployManifest(`${projectRoot}/web3api.deploy.yaml`); Object.entries(deployManifest.stages).forEach(([key, value]) => { @@ -66,39 +63,34 @@ const setup = async (domainNames: string[]) => { ], }); - // TODO: why not use the ENS wrapper here? for await (const domainName of domainNames) { - const label = "0x" + keccak256(domainName) - await client.query({ - uri: "w3://ens/ethereum.web3api.eth", - query: ` - mutation { - callContractMethodAndWait( - address: "${registrarAddress}", - method: "function register(bytes32 label, address owner)", - args: ["${label}", "${signer.address}"], - txOverrides: { - value: null, - nonce: null, - gasPrice: "50", - gasLimit: "200000" - } - ) - } - `, - }); - - await client.query({ - uri: "w3://ens/ethereum.web3api.eth", - query: ` - mutation { - callContractMethod( - address: "${ensAddress}", - method: "function setResolver(bytes32 node, address owner)", - args: ["${namehash(`${domainName}.eth`)}", "${resolverAddress}"] - ) - } - ` + await client.invoke({ + uri: "w3://ens/rinkeby/ens.web3api.eth", + module: "mutation", + method: "registerDomain", + input: { + domain: domainName, + owner: signer.address, + registrarAddress, + registryAddress: ensAddress, + connection: { + networkNameOrChainId: "testnet", + }, + }, + }) + + await client.invoke({ + uri: `w3://ens/rinkeby/ens.web3api.eth`, + module: "mutation", + method: "setResolver", + input: { + domain: domainName, + resolverAddress, + registryAddress: ensAddress, + connection: { + networkNameOrChainId: "testnet", + }, + }, }); } } @@ -134,7 +126,7 @@ describe("e2e tests for deploy command", () => { }); test("Successfully deploys the project", async () => { - const { exitCode: code, stdout: output, stderr } = await runCLI( + const { exitCode: code, stdout: output } = await runCLI( { args: ["deploy"], cwd: projectRoot, diff --git a/packages/js/test-env/src/index.ts b/packages/js/test-env/src/index.ts index 09ea3c2ecd..81280707ff 100644 --- a/packages/js/test-env/src/index.ts +++ b/packages/js/test-env/src/index.ts @@ -189,7 +189,6 @@ export async function buildAndDeployApi({ const ethersProvider = new ethers.providers.JsonRpcProvider(ethereumProvider); const owner = await ethersProvider.getSigner(0).getAddress(); - // TODO: deploy ENS wrapper to testenv const { error: registerError } = await client.invoke({ uri: `w3://ens/rinkeby/ens.web3api.eth`, module: "mutation", From 2582d08260445f85c5baf1d2516cefaf2a397e71 Mon Sep 17 00:00:00 2001 From: namesty Date: Thu, 21 Apr 2022 01:34:49 +0200 Subject: [PATCH 32/41] (fix): fixed buildAndDeploy signature in client env tests --- packages/js/client/src/__tests__/env.spec.ts | 58 ++++++++++++++------ 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/packages/js/client/src/__tests__/env.spec.ts b/packages/js/client/src/__tests__/env.spec.ts index 8cb5170d6b..b6bd365622 100644 --- a/packages/js/client/src/__tests__/env.spec.ts +++ b/packages/js/client/src/__tests__/env.spec.ts @@ -13,12 +13,16 @@ describe("env", () => { let ipfsProvider: string; let ethProvider: string; let ensAddress: string; + let ensRegistrarAddress: string; + let ensResolverAddress: string; beforeAll(async () => { - const { ipfs, ethereum, ensAddress: ens } = await initTestEnvironment(); + const { ipfs, ethereum, ensAddress: ens, resolverAddress, registrarAddress } = await initTestEnvironment(); ipfsProvider = ipfs; ethProvider = ethereum; ensAddress = ens; + ensRegistrarAddress = registrarAddress; + ensResolverAddress = resolverAddress; }); afterAll(async () => { @@ -83,11 +87,16 @@ describe("env", () => { let ensUri: string; beforeAll(async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-env-types`, + const deployClient = await getClient() + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/simple-env-types`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client: deployClient + }); ensUri = `ens/testnet/${api.ensDomain}`; @@ -256,11 +265,16 @@ describe("env", () => { let ensUri: string; beforeAll(async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/complex-env-types`, + const deployClient = await getClient(); + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/complex-env-types`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client: deployClient + }); ensUri = `ens/testnet/${api.ensDomain}`; @@ -442,11 +456,16 @@ describe("env", () => { let client: Client; beforeAll(async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/env-client-types`, + const deployClient = await getClient() + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/env-client-types`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client: deployClient + }); ensUri = `ens/testnet/${api.ensDomain}`; client = await getClient({ @@ -504,11 +523,16 @@ describe("env", () => { }); test("set env when not required", async () => { - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/enum-types`, + const deployClient = await getClient() + const api = await buildAndDeployApi({ + apiAbsPath: `${GetPathToTestApis()}/enum-types`, ipfsProvider, - ensAddress - ); + ensRegistryAddress: ensAddress, + ethereumProvider: ethProvider, + ensRegistrarAddress, + ensResolverAddress, + client: deployClient + }); const ensUri = `ens/testnet/${api.ensDomain}`; const client = await getClient({ From 3686653f5e30f6956644cee95eafd67643b0400a Mon Sep 17 00:00:00 2001 From: namesty Date: Fri, 22 Apr 2022 08:30:49 +0200 Subject: [PATCH 33/41] (chore): removed client usage for testEnv's deployment name registration --- packages/cli/src/__tests__/e2e/query.spec.ts | 21 +----- .../src/__tests__/Web3ApiClient.spec.ts | 34 +-------- packages/js/client/src/__tests__/env.spec.ts | 8 -- .../client/src/__tests__/resolveUri.spec.ts | 11 +-- .../js/plugins/ethereum/src/Connection.ts | 17 +++-- .../ethereum/src/__tests__/e2e.spec.ts | 1 - .../filesystem/src/__tests__/e2e.spec.ts | 1 - .../react/src/__tests__/integration.spec.tsx | 20 ----- .../src/__tests__/useWeb3ApiInvoke.spec.tsx | 19 ----- .../src/__tests__/useWeb3ApiQuery.spec.tsx | 19 ----- packages/js/test-env/package.json | 3 +- packages/js/test-env/src/index.ts | 73 ++++++++----------- .../src/__tests__/e2e/integration.spec.ts | 1 - yarn.lock | 2 +- 14 files changed, 53 insertions(+), 177 deletions(-) diff --git a/packages/cli/src/__tests__/e2e/query.spec.ts b/packages/cli/src/__tests__/e2e/query.spec.ts index d874adde1c..efc7c64f03 100644 --- a/packages/cli/src/__tests__/e2e/query.spec.ts +++ b/packages/cli/src/__tests__/e2e/query.spec.ts @@ -12,8 +12,6 @@ import { getSampleOutputWithClientConfig, ISampleOutputOptions, } from "./query.spec.helper"; -import { Web3ApiClient } from "@web3api/client-js"; -import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; const HELP = ` w3 query [options] @@ -70,22 +68,6 @@ describe("e2e tests for query command", () => { expect(deployErr).toBe(""); - const client = new Web3ApiClient({ - plugins: [ - { - uri: "w3://ens/ethereum.web3api.eth", - plugin: ethereumPlugin({ - networks: { - testnet: { - provider: ethereum, - } - }, - defaultNetwork: "testnet" - }), - } - ], - }); - await buildAndDeployApi({ apiAbsPath: projectRoot, ipfsProvider: ipfs, @@ -93,8 +75,7 @@ describe("e2e tests for query command", () => { ensRegistrarAddress: registrarAddress, ensResolverAddress: resolverAddress, ensRegistryAddress: ens, - ensName: "simplestorage.eth", - client + ensName: "simplestorage", }) }); diff --git a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts index 5b0b8331b0..1e93698fb1 100644 --- a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts +++ b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts @@ -48,7 +48,7 @@ describe("Web3ApiClient", () => { }); const getClient = async (config?: Partial) => { - return createWeb3ApiClient( + const client = await createWeb3ApiClient( { ethereum: { networks: { @@ -66,6 +66,8 @@ describe("Web3ApiClient", () => { }, config ); + + return client; }; const mockPlugin = () => { @@ -167,7 +169,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -243,7 +244,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -285,8 +285,7 @@ describe("Web3ApiClient", () => { ensRegistryAddress: ensAddress, ethereumProvider: ethProvider, ensRegistrarAddress, - ensResolverAddress, - client + ensResolverAddress }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -703,7 +702,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -947,7 +945,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -1127,7 +1124,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -1363,7 +1359,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -1435,7 +1430,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -1523,7 +1517,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -1562,7 +1555,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -1646,7 +1638,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; const largeStr = new Array(10000).join("web3api "); @@ -1702,7 +1693,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -1855,7 +1845,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -2025,8 +2014,6 @@ describe("Web3ApiClient", () => { }); it("e2e interface implementations", async () => { - const deployClient = await getClient(); - let interfaceApi = await buildAndDeployApi({ apiAbsPath: `${GetPathToTestApis()}/implementations/test-interface`, ipfsProvider, @@ -2034,7 +2021,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client: deployClient }); const interfaceUri = `w3://ens/testnet/${interfaceApi.ensDomain}`; @@ -2045,7 +2031,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client: deployClient }); const implementationUri = `w3://ens/testnet/${implementationApi.ensDomain}`; @@ -2134,7 +2119,6 @@ describe("Web3ApiClient", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -2273,7 +2257,6 @@ enum Logger_LogLevel @imported( ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -2327,7 +2310,6 @@ enum Logger_LogLevel @imported( ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -2428,7 +2410,6 @@ enum Logger_LogLevel @imported( ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; const ipfsUri = `ipfs/${api.ipfsCid}`; @@ -2533,7 +2514,6 @@ enum Logger_LogLevel @imported( ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; @@ -2565,7 +2545,6 @@ enum Logger_LogLevel @imported( it("e2e getImplementations capability", async () => { const interfaceUri = "w3://ens/interface.eth"; - const deployClient = await getClient(); const implementationApi = await buildAndDeployApi({ apiAbsPath: `${GetPathToTestApis()}/implementations/test-use-getImpl`, @@ -2574,7 +2553,6 @@ enum Logger_LogLevel @imported( ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client: deployClient }); const implementationUri = `w3://ens/testnet/${implementationApi.ensDomain}`; @@ -2613,7 +2591,6 @@ enum Logger_LogLevel @imported( it("e2e Interface invoke method", async () => { const interfaceUri = "w3://ens/interface.eth"; - const deployClient = await getClient(); // Build interface polywrapper await runCLI({ args: ["build"], @@ -2627,7 +2604,6 @@ enum Logger_LogLevel @imported( ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client: deployClient }); const implementationUri = `w3://ens/testnet/${implementationApi.ensDomain}`; @@ -2647,7 +2623,6 @@ enum Logger_LogLevel @imported( ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const apiUri = `w3://ens/testnet/${api.ensDomain}`; @@ -2697,7 +2672,6 @@ enum Logger_LogLevel @imported( ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = `ens/testnet/${api.ensDomain}`; diff --git a/packages/js/client/src/__tests__/env.spec.ts b/packages/js/client/src/__tests__/env.spec.ts index b6bd365622..00fe90ce6b 100644 --- a/packages/js/client/src/__tests__/env.spec.ts +++ b/packages/js/client/src/__tests__/env.spec.ts @@ -87,7 +87,6 @@ describe("env", () => { let ensUri: string; beforeAll(async () => { - const deployClient = await getClient() const api = await buildAndDeployApi({ apiAbsPath: `${GetPathToTestApis()}/simple-env-types`, ipfsProvider, @@ -95,7 +94,6 @@ describe("env", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client: deployClient }); ensUri = `ens/testnet/${api.ensDomain}`; @@ -265,7 +263,6 @@ describe("env", () => { let ensUri: string; beforeAll(async () => { - const deployClient = await getClient(); const api = await buildAndDeployApi({ apiAbsPath: `${GetPathToTestApis()}/complex-env-types`, ipfsProvider, @@ -273,7 +270,6 @@ describe("env", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client: deployClient }); ensUri = `ens/testnet/${api.ensDomain}`; @@ -456,7 +452,6 @@ describe("env", () => { let client: Client; beforeAll(async () => { - const deployClient = await getClient() const api = await buildAndDeployApi({ apiAbsPath: `${GetPathToTestApis()}/env-client-types`, ipfsProvider, @@ -464,7 +459,6 @@ describe("env", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client: deployClient }); ensUri = `ens/testnet/${api.ensDomain}`; @@ -523,7 +517,6 @@ describe("env", () => { }); test("set env when not required", async () => { - const deployClient = await getClient() const api = await buildAndDeployApi({ apiAbsPath: `${GetPathToTestApis()}/enum-types`, ipfsProvider, @@ -531,7 +524,6 @@ describe("env", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client: deployClient }); const ensUri = `ens/testnet/${api.ensDomain}`; diff --git a/packages/js/client/src/__tests__/resolveUri.spec.ts b/packages/js/client/src/__tests__/resolveUri.spec.ts index 50ab7351e0..11b5f636e8 100644 --- a/packages/js/client/src/__tests__/resolveUri.spec.ts +++ b/packages/js/client/src/__tests__/resolveUri.spec.ts @@ -262,7 +262,6 @@ describe("Web3ApiClient - resolveUri", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = new Uri(`ens/testnet/${deployResult.ensDomain}`); @@ -364,7 +363,6 @@ describe("Web3ApiClient - resolveUri", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = new Uri(`ens/testnet/${deployResult.ensDomain}`); @@ -495,7 +493,6 @@ describe("Web3ApiClient - resolveUri", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = new Uri(`ens/testnet/${deployResult.ensDomain}`); @@ -627,7 +624,6 @@ describe("Web3ApiClient - resolveUri", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = new Uri(`ens/testnet/${deployResult.ensDomain}`); @@ -766,8 +762,6 @@ describe("Web3ApiClient - resolveUri", () => { cwd: `${GetPathToTestApis()}/interface-invoke/test-interface`, }); - const client = await getClient(); - const deployResult = await buildAndDeployApi({ apiAbsPath: `${GetPathToTestApis()}/interface-invoke/test-api`, ipfsProvider, @@ -775,14 +769,13 @@ describe("Web3ApiClient - resolveUri", () => { ethereumProvider: ethProvider, ensRegistrarAddress, ensResolverAddress, - client }); const ensUri = new Uri(`ens/testnet/${deployResult.ensDomain}`); const ipfsUri = new Uri(`ipfs/${deployResult.ipfsCid}`); const redirectUri = new Uri(`ens/redirect.eth`); - const clientWithRedirects = await getClient({ + const client = await getClient({ redirects: [ { from: ipfsUri.uri, @@ -791,7 +784,7 @@ describe("Web3ApiClient - resolveUri", () => { ], }); - const result = await clientWithRedirects.resolveUri(ensUri); + const result = await client.resolveUri(ensUri); expect(result.api).toBeFalsy(); expect(result.uri).toEqual(redirectUri); diff --git a/packages/js/plugins/ethereum/src/Connection.ts b/packages/js/plugins/ethereum/src/Connection.ts index f537293190..2ba764a8ce 100644 --- a/packages/js/plugins/ethereum/src/Connection.ts +++ b/packages/js/plugins/ethereum/src/Connection.ts @@ -67,10 +67,15 @@ export class Connection { networkish = networkish.toLowerCase(); } + const provider = (ethers.providers.getDefaultProvider( + ethers.providers.getNetwork(networkish), + { + infura: "a817ee00c2714fe3a908c91d5713d302", + } + ) as unknown) as JsonRpcProvider; + return new Connection({ - provider: (ethers.providers.getDefaultProvider( - ethers.providers.getNetwork(networkish) - ) as unknown) as JsonRpcProvider, + provider, }); } @@ -87,9 +92,9 @@ export class Connection { this._config.provider = provider; if (typeof provider === "string") { - this._client = (ethers.providers.getDefaultProvider( - provider - ) as unknown) as JsonRpcProvider | WebSocketProvider; + this._client = (ethers.providers.getDefaultProvider(provider, { + infura: "a817ee00c2714fe3a908c91d5713d302", + }) as unknown) as JsonRpcProvider | WebSocketProvider; } else { if ((provider as JsonRpcProvider).anyNetwork !== undefined) { this._client = provider as JsonRpcProvider; diff --git a/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts b/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts index 7d38a32462..74e1bf6d52 100644 --- a/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts +++ b/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts @@ -83,7 +83,6 @@ describe("Ethereum Plugin", () => { ensRegistryAddress: ensAddress, ensRegistrarAddress: registrarAddress, ensResolverAddress: resolverAddress, - client, ethereumProvider: ethereum, }); diff --git a/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts b/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts index b57f067350..53e8491fe2 100644 --- a/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts +++ b/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts @@ -88,7 +88,6 @@ describe("Filesystem plugin", () => { ensRegistrarAddress, ensResolverAddress, ethereumProvider, - client }); const fsPath = `${apiPath}/build`; const fsUri = `fs/${fsPath}`; diff --git a/packages/js/react/src/__tests__/integration.spec.tsx b/packages/js/react/src/__tests__/integration.spec.tsx index 7137db217d..6cac5c573f 100644 --- a/packages/js/react/src/__tests__/integration.spec.tsx +++ b/packages/js/react/src/__tests__/integration.spec.tsx @@ -13,9 +13,6 @@ import { PluginRegistration } from "@web3api/core-js"; // eslint-disable-next-line import/no-extraneous-dependencies import React from "react"; import { render, fireEvent, screen, waitFor } from "@testing-library/react"; -import { Web3ApiClient } from "@web3api/client-js"; -import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; - jest.setTimeout(360000); describe("Web3API React Integration", () => { @@ -37,22 +34,6 @@ describe("Web3API React Integration", () => { plugins = createPlugins(ensAddress, ethereum, ipfs); - const client = new Web3ApiClient({ - plugins: [ - { - uri: "w3://ens/ethereum.web3api.eth", - plugin: ethereumPlugin({ - networks: { - testnet: { - provider: ethereum, - } - }, - defaultNetwork: "testnet" - }), - } - ], - }); - api = await buildAndDeployApi({ apiAbsPath: `${GetPathToTestApis()}/simple-storage`, ipfsProvider: ipfs, @@ -60,7 +41,6 @@ describe("Web3API React Integration", () => { ensRegistrarAddress: registrarAddress, ensRegistryAddress: ensAddress, ensResolverAddress: resolverAddress, - client }); ensUri = `ens/testnet/${api.ensDomain}`; diff --git a/packages/js/react/src/__tests__/useWeb3ApiInvoke.spec.tsx b/packages/js/react/src/__tests__/useWeb3ApiInvoke.spec.tsx index 1287cc9789..d91f75bb3e 100644 --- a/packages/js/react/src/__tests__/useWeb3ApiInvoke.spec.tsx +++ b/packages/js/react/src/__tests__/useWeb3ApiInvoke.spec.tsx @@ -20,8 +20,6 @@ import { RenderHookOptions, cleanup } from "@testing-library/react-hooks"; -import { Web3ApiClient } from "@web3api/client-js"; -import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; jest.setTimeout(360000); @@ -39,22 +37,6 @@ describe("useWeb3ApiInvoke hook", () => { resolverAddress } = await initTestEnvironment(); - const client = new Web3ApiClient({ - plugins: [ - { - uri: "w3://ens/ethereum.web3api.eth", - plugin: ethereumPlugin({ - networks: { - testnet: { - provider: ethereum, - } - }, - defaultNetwork: "testnet" - }), - } - ], - }); - const { ensDomain } = await buildAndDeployApi({ apiAbsPath: `${GetPathToTestApis()}/simple-storage`, ipfsProvider: ipfs, @@ -62,7 +44,6 @@ describe("useWeb3ApiInvoke hook", () => { ensRegistrarAddress: registrarAddress, ensRegistryAddress: ensAddress, ensResolverAddress: resolverAddress, - client }); uri = `ens/testnet/${ensDomain}`; diff --git a/packages/js/react/src/__tests__/useWeb3ApiQuery.spec.tsx b/packages/js/react/src/__tests__/useWeb3ApiQuery.spec.tsx index f36cf23467..b59066f4db 100644 --- a/packages/js/react/src/__tests__/useWeb3ApiQuery.spec.tsx +++ b/packages/js/react/src/__tests__/useWeb3ApiQuery.spec.tsx @@ -22,8 +22,6 @@ import { RenderHookOptions, cleanup } from "@testing-library/react-hooks"; -import { Web3ApiClient } from "@web3api/client-js"; -import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; jest.setTimeout(360000); @@ -41,22 +39,6 @@ describe("useWeb3ApiQuery hook", () => { resolverAddress } = await initTestEnvironment(); - const client = new Web3ApiClient({ - plugins: [ - { - uri: "w3://ens/ethereum.web3api.eth", - plugin: ethereumPlugin({ - networks: { - testnet: { - provider: ethereum, - } - }, - defaultNetwork: "testnet" - }), - } - ], - }); - const { ensDomain } = await buildAndDeployApi({ apiAbsPath: `${GetPathToTestApis()}/simple-storage`, ipfsProvider: ipfs, @@ -64,7 +46,6 @@ describe("useWeb3ApiQuery hook", () => { ensRegistrarAddress: registrarAddress, ensRegistryAddress: ensAddress, ensResolverAddress: resolverAddress, - client }); uri = `ens/testnet/${ensDomain}`; diff --git a/packages/js/test-env/package.json b/packages/js/test-env/package.json index 76e062cff6..fc9c73dd38 100644 --- a/packages/js/test-env/package.json +++ b/packages/js/test-env/package.json @@ -20,7 +20,8 @@ "spawn-command": "0.0.2-1", "@web3api/core-js": "0.0.1-prealpha.71", "ethers": "5.6.4", - "js-yaml": "4.1.0" + "js-yaml": "4.1.0", + "js-sha3": "0.8.0" }, "devDependencies": { "rimraf": "3.0.2", diff --git a/packages/js/test-env/src/index.ts b/packages/js/test-env/src/index.ts index 81280707ff..f96bd15253 100644 --- a/packages/js/test-env/src/index.ts +++ b/packages/js/test-env/src/index.ts @@ -4,7 +4,9 @@ import axios from "axios"; import fs from "fs"; import { ethers } from "ethers"; import yaml from "js-yaml"; -import { Client, deserializeWeb3ApiManifest, Uri } from "@web3api/core-js"; +import { keccak256 } from "js-sha3"; +import { deserializeWeb3ApiManifest, Uri } from "@web3api/core-js"; +import { namehash } from "ethers/lib/utils"; interface TestEnvironment { ipfs: string; @@ -137,7 +139,6 @@ export async function buildAndDeployApi({ ensResolverAddress, ethereumProvider, ensName, - client, }: { apiAbsPath: string; ipfsProvider: string; @@ -146,7 +147,6 @@ export async function buildAndDeployApi({ ensResolverAddress: string; ethereumProvider: string; ensName?: string; - client: Client; }): Promise<{ ensDomain: string; ipfsCid: string; @@ -161,7 +161,8 @@ export async function buildAndDeployApi({ ); // create a new ENS domain - const apiEns = ensName ?? `${generateName()}.eth`; + const domainName = ensName ?? generateName(); + const apiEns = `${domainName}.eth`; // build API const { @@ -187,48 +188,38 @@ export async function buildAndDeployApi({ // register ENS domain const ethersProvider = new ethers.providers.JsonRpcProvider(ethereumProvider); - const owner = await ethersProvider.getSigner(0).getAddress(); + const signer = await ethersProvider.getSigner(0); + const owner = await signer.getAddress(); - const { error: registerError } = await client.invoke({ - uri: `w3://ens/rinkeby/ens.web3api.eth`, - module: "mutation", - method: "registerDomain", - input: { - domain: apiEns, - owner, - registrarAddress: ensRegistrarAddress, - registryAddress: ensRegistryAddress, - connection: { - networkNameOrChainId: "testnet", - }, - }, - }); + const label = "0x" + keccak256(domainName); - if (registerError) { - throw new Error( - `Error publishing API to ENS. Path: ${apiAbsPath}. Error: ${registerError}` - ); - } + const ensRegistrarContract = new ethers.Contract( + ensRegistrarAddress, + ["function register(bytes32 label, address owner)"], + signer + ); - const { error: setResolverError } = await client.invoke({ - uri: `w3://ens/rinkeby/ens.web3api.eth`, - module: "mutation", - method: "setResolver", - input: { - domain: apiEns, - resolverAddress: ensResolverAddress, - registryAddress: ensRegistryAddress, - connection: { - networkNameOrChainId: "testnet", - }, - }, + const ensRegistryContract = new ethers.Contract( + ensRegistryAddress, + ["function setResolver(bytes32 node, address owner)"], + signer + ); + + const registerTx = await ensRegistrarContract.register(label, owner, { + value: null, + nonce: null, + gasPrice: "50", + gasLimit: "200000", }); - if (setResolverError) { - throw new Error( - `Error publishing API to ENS. Path: ${apiAbsPath}. Error: ${setResolverError}` - ); - } + await registerTx.wait(); + + const setResolverTx = await ensRegistryContract.setResolver( + namehash(apiEns), + ensResolverAddress + ); + + await setResolverTx.wait(); // manually configure manifests diff --git a/packages/templates/api/assemblyscript/src/__tests__/e2e/integration.spec.ts b/packages/templates/api/assemblyscript/src/__tests__/e2e/integration.spec.ts index 675bf1da8b..8bbf3d45e2 100644 --- a/packages/templates/api/assemblyscript/src/__tests__/e2e/integration.spec.ts +++ b/packages/templates/api/assemblyscript/src/__tests__/e2e/integration.spec.ts @@ -43,7 +43,6 @@ describe("SimpleStorage", () => { ensRegistryAddress: ensAddress, ensRegistrarAddress: registrarAddress, ensResolverAddress: resolverAddress, - client, ethereumProvider: testEnvEtherem, }); diff --git a/yarn.lock b/yarn.lock index af7e4c3380..aeeb97274d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15254,7 +15254,7 @@ multicodec@^3.0.1: uint8arrays "^3.0.0" varint "^6.0.0" -multiformats@^9.4.2: +multiformats@9.6.4, multiformats@^9.4.2: version "9.6.4" resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.6.4.tgz#5dce1f11a407dbb69aa612cb7e5076069bb759ca" integrity sha512-fCCB6XMrr6CqJiHNjfFNGT0v//dxOBMrOMqUIzpPc/mmITweLEyhvMpY9bF+jZ9z3vaMAau5E8B68DW77QMXkg== From f73fb01dbad6f53483807f83dea142beb49ab331 Mon Sep 17 00:00:00 2001 From: namesty Date: Fri, 22 Apr 2022 09:37:02 +0200 Subject: [PATCH 34/41] (fix): minor fixes for CLI tests --- packages/js/test-env/package.json | 1 - packages/js/test-env/src/index.ts | 1 + yarn.lock | 88 ++++++++++++++++++++----------- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/packages/js/test-env/package.json b/packages/js/test-env/package.json index 64f1042b61..38dc1bc9e5 100644 --- a/packages/js/test-env/package.json +++ b/packages/js/test-env/package.json @@ -19,7 +19,6 @@ "@web3api/core-js": "0.0.1-prealpha.72", "axios": "0.21.2", "spawn-command": "0.0.2-1", - "@web3api/core-js": "0.0.1-prealpha.71", "ethers": "5.6.4", "js-yaml": "4.1.0", "js-sha3": "0.8.0" diff --git a/packages/js/test-env/src/index.ts b/packages/js/test-env/src/index.ts index 4305ce7c5a..6c82578596 100644 --- a/packages/js/test-env/src/index.ts +++ b/packages/js/test-env/src/index.ts @@ -233,6 +233,7 @@ export async function buildAndDeployApi({ tempManifestPath, yaml.dump({ ...web3apiManifest, + format: "0.0.1-prealpha.8", deploy: `./${tempDeployManifestFilename}`, }) ); diff --git a/yarn.lock b/yarn.lock index 19ccfff2d6..5ab92cfbe8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1497,6 +1497,32 @@ is-absolute "^1.0.0" is-negated-glob "^1.0.0" +"@ensdomains/address-encoder@^0.1.7": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz#f948c485443d9ef7ed2c0c4790e931c33334d02d" + integrity sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg== + dependencies: + bech32 "^1.1.3" + blakejs "^1.1.0" + bn.js "^4.11.8" + bs58 "^4.0.1" + crypto-addr-codec "^0.1.7" + nano-base32 "^1.0.1" + ripemd160 "^2.0.2" + +"@ensdomains/ens@0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.3.tgz#f4a6b55146fe526c9a50e13f373bf90d36ca94dc" + integrity sha512-btC+fGze//ml8SMNCx5DgwM8+kG2t+qDCZrqlL/2+PV4CNxnRIpR3egZ49D9FqS52PFoYLmz6MaQfl7AO3pUMA== + dependencies: + bluebird "^3.5.2" + eth-ens-namehash "^2.0.8" + ethereumjs-testrpc "^6.0.3" + ganache-cli "^6.1.0" + solc "^0.4.20" + testrpc "0.0.1" + web3-utils "^1.0.0-beta.31" + "@ensdomains/ens@0.4.4": version "0.4.4" resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.4.tgz#05e7bb138471a5e5844b4c1f263ec0ad7edcd272" @@ -1560,10 +1586,10 @@ "@ethersproject/properties" ">=5.0.0-beta.131" "@ethersproject/strings" ">=5.0.0-beta.130" -"@ethersproject/abi@^5.0.0", "@ethersproject/abi@^5.6.0": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.1.tgz#f7de888edeb56b0a657b672bdd1b3a1135cd14f7" - integrity sha512-0cqssYh6FXjlwKWBmLm3+zH2BNARoS5u/hxbz+LpQmcDB3w0W553h2btWui1/uZp2GBM/SI3KniTuMcYyHpA5w== +"@ethersproject/abi@5.6.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.0.tgz#ea07cbc1eec2374d32485679c12408005895e9f3" + integrity sha512-AhVByTwdXCc2YQ20v300w6KVHle9g2OFc28ZAFCPnJyEpkv1xKXjZcSTgWOlv1i+0dqlgF8RCF2Rn2KC1t+1Vg== dependencies: "@ethersproject/address" "^5.6.0" "@ethersproject/bignumber" "^5.6.0" @@ -1651,7 +1677,7 @@ "@ethersproject/bytes" "^5.0.9" "@ethersproject/properties" "^5.0.7" -"@ethersproject/basex@^5.0.3", "@ethersproject/basex@^5.6.0": +"@ethersproject/basex@5.6.0", "@ethersproject/basex@^5.0.3", "@ethersproject/basex@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.6.0.tgz#9ea7209bf0a1c3ddc2a90f180c3a7f0d7d2e8a69" integrity sha512-qN4T+hQd/Md32MoJpc69rOwLYRUXwjTlhHDIeUkUmiN/JyWkkLLMoG0TqvSQKNqZOMgN5stbUYN6ILC+eD7MEQ== @@ -1668,7 +1694,7 @@ "@ethersproject/logger" "^5.6.0" bn.js "^4.11.9" -"@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.0.9", "@ethersproject/bytes@^5.6.0": +"@ethersproject/bytes@5.6.1", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.0.9", "@ethersproject/bytes@^5.6.0": version "5.6.1" resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.6.1.tgz#24f916e411f82a8a60412344bf4a813b917eefe7" integrity sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g== @@ -1762,10 +1788,10 @@ resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.6.0.tgz#d7db1bfcc22fd2e4ab574cba0bb6ad779a9a3e7a" integrity sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg== -"@ethersproject/networks@^5.0.0", "@ethersproject/networks@^5.0.3", "@ethersproject/networks@^5.6.0": - version "5.6.2" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.2.tgz#2bacda62102c0b1fcee408315f2bed4f6fbdf336" - integrity sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA== +"@ethersproject/networks@5.6.1": + version "5.6.1" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.1.tgz#7a21ed1f83e86121737b16841961ec99ccf5c9c7" + integrity sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg== dependencies: "@ethersproject/logger" "^5.6.0" @@ -1784,7 +1810,7 @@ "@ethersproject/bytes" "^5.6.0" "@ethersproject/sha2" "^5.6.0" -"@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.0", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.0.7", "@ethersproject/properties@^5.6.0": +"@ethersproject/properties@5.6.0", "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.0", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.0.7", "@ethersproject/properties@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.6.0.tgz#38904651713bc6bdd5bdd1b0a4287ecda920fa04" integrity sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg== @@ -1816,10 +1842,10 @@ bech32 "1.1.4" ws "7.2.3" -"@ethersproject/providers@^5.0.0": - version "5.6.4" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.4.tgz#1a49c211b57b0b2703c320819abbbfa35c83dff7" - integrity sha512-WAdknnaZ52hpHV3qPiJmKx401BLpup47h36Axxgre9zT+doa/4GC/Ne48ICPxTm0BqndpToHjpLP1ZnaxyE+vw== +"@ethersproject/providers@5.6.2": + version "5.6.2" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.2.tgz#b9807b1c8c6f59fa2ee4b3cf6519724d07a9f422" + integrity sha512-6/EaFW/hNWz+224FXwl8+HdMRzVHt8DpPmu5MZaIQqx/K/ELnC9eY236SMV7mleCM3NnEArFwcAAxH5kUUgaRg== dependencies: "@ethersproject/abstract-provider" "^5.6.0" "@ethersproject/abstract-signer" "^5.6.0" @@ -7413,17 +7439,17 @@ copyfiles@2.4.1: yargs "^16.1.0" core-js-compat@^3.0.0, core-js-compat@^3.20.2, core-js-compat@^3.21.0, core-js-compat@^3.6.2: - version "3.22.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.1.tgz#47b9c5e79efbf13935f637449fa1cdec8cd9515f" - integrity sha512-CWbNqTluLMvZg1cjsQUbGiCM91dobSHKfDIyCoxuqxthdjGuUlaMbCsSehP3CBiVvG0C7P6UIrC1v0hgFE75jw== + version "3.22.2" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.2.tgz#eec621eb276518efcf718d0a6d9d042c3d0cad48" + integrity sha512-Fns9lU06ZJ07pdfmPMu7OnkIKGPKDzXKIiuGlSvHHapwqMUF2QnnsWwtueFZtSyZEilP0o6iUeHQwpn7LxtLUw== dependencies: browserslist "^4.20.2" semver "7.0.0" core-js-pure@^3.20.2: - version "3.22.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.1.tgz#4d94e0c9a7b710da20dadd727fe98b43543119f0" - integrity sha512-TChjCtgcMDc8t12RiwAsThjqrS/VpBlEvDgL009ot4HESzBo3h2FSZNa6ZS1nWKZEPDoulnszxUll9n0/spflQ== + version "3.22.2" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.2.tgz#c10bffdc3028d25c2aae505819a05543db61544f" + integrity sha512-Lb+/XT4WC4PaCWWtZpNPaXmjiNDUe5CJuUtbkMrIM1kb1T/jJoAIp+bkVP/r5lHzMr+ZAAF8XHp7+my6Ol0ysQ== core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5: version "2.6.12" @@ -7431,9 +7457,9 @@ core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.5: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.5.0: - version "3.22.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.1.tgz#1936e4f1da82675fe22ae10ee60ef638cd9752fd" - integrity sha512-l6CwCLq7XgITOQGhv1dIUmwCFoqFjyQ6zQHUCQlS0xKmb9d6OHIg8jDiEoswhaettT21BSF5qKr6kbvE+aKwxw== + version "3.22.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.2.tgz#3ea0a245b0895fa39d1faa15fe75d91ade504a01" + integrity sha512-Z5I2vzDnEIqO2YhELVMFcL1An2CIsFe9Q7byZhs8c/QxummxZlAHw33TUHbIte987LkisOgL0LwQ1P9D6VISnA== core-util-is@1.0.2: version "1.0.2" @@ -8418,9 +8444,9 @@ electron-fetch@^1.7.2: encoding "^0.1.13" electron-to-chromium@^1.3.378, electron-to-chromium@^1.3.47, electron-to-chromium@^1.4.84: - version "1.4.115" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.115.tgz#62d68576385f17e9b268b04e98cc132ed04c6671" - integrity sha512-yy1W7cTcreskCWSRTtvp8CNLEci3uYBn5s1U4IytDz7v485iLVPh4QwFuSCavsFbxRLVvwnHNXEFIDShrk/UnQ== + version "1.4.118" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.118.tgz#2d917c71712dac9652cc01af46c7d0bd51552974" + integrity sha512-maZIKjnYDvF7Fs35nvVcyr44UcKNwybr93Oba2n3HkKDFAtk0svERkLN/HyczJDS3Fo4wU9th9fUQd09ZLtj1w== elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" @@ -14836,7 +14862,7 @@ multicodec@^3.0.1: uint8arrays "^3.0.0" varint "^6.0.0" -multiformats@9.6.4, multiformats@^9.4.2: +multiformats@^9.4.2: version "9.6.4" resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.6.4.tgz#5dce1f11a407dbb69aa612cb7e5076069bb759ca" integrity sha512-fCCB6XMrr6CqJiHNjfFNGT0v//dxOBMrOMqUIzpPc/mmITweLEyhvMpY9bF+jZ9z3vaMAau5E8B68DW77QMXkg== @@ -19903,9 +19929,9 @@ tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" - integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== tsutils@^3.17.1: version "3.21.0" From f0ced86f72654178dd1b07a80b17b2dcc6d5bfda Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 22 Apr 2022 18:16:21 -0700 Subject: [PATCH 35/41] fix http test --- packages/js/plugins/http/src/__tests__/e2e/integration.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/js/plugins/http/src/__tests__/e2e/integration.spec.ts b/packages/js/plugins/http/src/__tests__/e2e/integration.spec.ts index 5027811597..cb8e69a16d 100644 --- a/packages/js/plugins/http/src/__tests__/e2e/integration.spec.ts +++ b/packages/js/plugins/http/src/__tests__/e2e/integration.spec.ts @@ -80,7 +80,6 @@ describe("e2e tests for HttpPlugin", () => { ensRegistryAddress: ensAddress, ensRegistrarAddress: registrarAddress, ensResolverAddress: resolverAddress, - client, ethereumProvider: ethereum }); From e2cfabc691f83dda5dd12a5131ec597dda23f97b Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Mon, 25 Apr 2022 23:28:54 -0600 Subject: [PATCH 36/41] lint fix --- packages/js/plugins/logger/src/query/index.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/js/plugins/logger/src/query/index.ts b/packages/js/plugins/logger/src/query/index.ts index e3f320b668..55eb2e67a6 100644 --- a/packages/js/plugins/logger/src/query/index.ts +++ b/packages/js/plugins/logger/src/query/index.ts @@ -1,9 +1,4 @@ -import { - Module, - Input_log, - Logger_LogLevel, - Logger_LogLevelEnum, -} from "./w3"; +import { Module, Input_log, Logger_LogLevel, Logger_LogLevelEnum } from "./w3"; export type LogFunc = (level: Logger_LogLevel, message: string) => boolean; From c4f339c3fe5e6856b396be1136d9b53126ef6b52 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 26 Apr 2022 00:20:10 -0600 Subject: [PATCH 37/41] fix cli tests --- packages/cli/src/__tests__/e2e/build.spec.ts | 2 +- packages/cli/src/__tests__/e2e/deploy.spec.ts | 65 +++++++++++-------- packages/cli/src/__tests__/e2e/help.spec.ts | 1 - packages/cli/src/__tests__/e2e/query.spec.ts | 2 +- .../cli/src/__tests__/unit/docker.spec.ts | 2 +- .../cases/cli/api/build-cmd/.gitignore | 1 + .../build-cmd/001-sanity/expected/output.json | 8 +++ .../cli/api/build-cmd/001-sanity/package.json | 15 +++++ .../001-sanity/src/mutation/index.ts | 5 ++ .../001-sanity/src/mutation/schema.graphql | 5 ++ .../build-cmd/001-sanity/src/query/index.ts | 5 ++ .../001-sanity/src/query/schema.graphql | 5 ++ .../build-cmd/001-sanity/web3api.build.yaml | 6 ++ .../cli/api/build-cmd/001-sanity/web3api.yaml | 11 ++++ .../expected/output.json | 7 ++ .../002-invalid-manifest-1/web3api.yaml | 15 +++++ .../expected/output.json | 4 ++ .../003-invalid-manifest-2/web3api.yaml | 15 +++++ .../004-default-build/expected/output.json | 8 +++ .../build-cmd/004-default-build/package.json | 15 +++++ .../004-default-build/src/mutation/index.ts | 5 ++ .../src/mutation/schema.graphql | 5 ++ .../004-default-build/src/query/index.ts | 5 ++ .../src/query/schema.graphql | 5 ++ .../build-cmd/004-default-build/web3api.yaml | 10 +++ .../expected/output.json | 8 +++ .../005-default-dockerfile/package.json | 15 +++++ .../src/mutation/index.ts | 5 ++ .../src/mutation/schema.graphql | 5 ++ .../005-default-dockerfile/src/query/index.ts | 5 ++ .../src/query/schema.graphql | 5 ++ .../005-default-dockerfile/web3api.build.yaml | 9 +++ .../005-default-dockerfile/web3api.yaml | 11 ++++ .../006-custom-dockerfile/Dockerfile | 45 +++++++++++++ .../expected/output.json | 8 +++ .../006-custom-dockerfile/package.json | 15 +++++ .../src/mutation/index.ts | 5 ++ .../src/mutation/schema.graphql | 5 ++ .../006-custom-dockerfile/src/query/index.ts | 5 ++ .../src/query/schema.graphql | 5 ++ .../006-custom-dockerfile/web3api.build.yaml | 11 ++++ .../006-custom-dockerfile/web3api.yaml | 11 ++++ .../007-linked-packages/expected/output.json | 8 +++ .../007-linked-packages/package.json | 15 +++++ .../007-linked-packages/src/mutation/index.ts | 5 ++ .../src/mutation/schema.graphql | 5 ++ .../007-linked-packages/src/query/index.ts | 5 ++ .../src/query/schema.graphql | 5 ++ .../007-linked-packages/web3api.build.yaml | 13 ++++ .../007-linked-packages/web3api.yaml | 11 ++++ .../008-metadata/expected/output.json | 13 ++++ .../api/build-cmd/008-metadata/meta/icon.png | 1 + .../api/build-cmd/008-metadata/meta/link.svg | 1 + .../build-cmd/008-metadata/meta/test.graphql | 1 + .../api/build-cmd/008-metadata/meta/test.json | 1 + .../api/build-cmd/008-metadata/package.json | 15 +++++ .../008-metadata/src/mutation/index.ts | 5 ++ .../008-metadata/src/mutation/schema.graphql | 5 ++ .../build-cmd/008-metadata/src/query/index.ts | 5 ++ .../008-metadata/src/query/schema.graphql | 5 ++ .../build-cmd/008-metadata/web3api.build.yaml | 6 ++ .../build-cmd/008-metadata/web3api.meta.yaml | 19 ++++++ .../api/build-cmd/008-metadata/web3api.yaml | 12 ++++ .../cli/api/deploy/001-sanity/.gitignore | 1 + .../cli/api/deploy/001-sanity/package.json | 18 +++++ .../api/deploy/001-sanity/src/query/index.ts | 5 ++ .../001-sanity/src/query/schema.graphql | 3 + .../api/deploy/001-sanity/web3api.build.yaml | 6 ++ .../api/deploy/001-sanity/web3api.deploy.yaml | 26 ++++++++ .../cli/api/deploy/001-sanity/web3api.yaml | 9 +++ .../cli/api/deploy/002-no-ext/.gitignore | 1 + .../cli/api/deploy/002-no-ext/package.json | 18 +++++ .../api/deploy/002-no-ext/src/query/index.ts | 5 ++ .../002-no-ext/src/query/schema.graphql | 3 + .../api/deploy/002-no-ext/web3api.build.yaml | 6 ++ .../api/deploy/002-no-ext/web3api.deploy.yaml | 7 ++ .../cli/api/deploy/002-no-ext/web3api.yaml | 9 +++ .../api/deploy/003-invalid-config/.gitignore | 1 + .../deploy/003-invalid-config/package.json | 18 +++++ .../003-invalid-config/src/query/index.ts | 5 ++ .../src/query/schema.graphql | 3 + .../003-invalid-config/web3api.build.yaml | 6 ++ .../003-invalid-config/web3api.deploy.yaml | 12 ++++ .../deploy/003-invalid-config/web3api.yaml | 9 +++ .../api/deploy/004-fail-between/.gitignore | 1 + .../api/deploy/004-fail-between/package.json | 18 +++++ .../004-fail-between/src/query/index.ts | 5 ++ .../004-fail-between/src/query/schema.graphql | 3 + .../004-fail-between/web3api.build.yaml | 6 ++ .../004-fail-between/web3api.deploy.yaml | 19 ++++++ .../api/deploy/004-fail-between/web3api.yaml | 9 +++ 91 files changed, 756 insertions(+), 32 deletions(-) create mode 100644 packages/test-cases/cases/cli/api/build-cmd/.gitignore create mode 100644 packages/test-cases/cases/cli/api/build-cmd/001-sanity/expected/output.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/001-sanity/package.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/mutation/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/mutation/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/query/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/query/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/001-sanity/web3api.build.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/001-sanity/web3api.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/002-invalid-manifest-1/expected/output.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/002-invalid-manifest-1/web3api.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/003-invalid-manifest-2/expected/output.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/003-invalid-manifest-2/web3api.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/004-default-build/expected/output.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/004-default-build/package.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/mutation/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/mutation/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/query/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/query/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/004-default-build/web3api.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/expected/output.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/package.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/mutation/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/mutation/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/query/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/query/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/web3api.build.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/web3api.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/Dockerfile create mode 100644 packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/expected/output.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/package.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/mutation/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/mutation/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/query/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/query/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/web3api.build.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/web3api.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/expected/output.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/package.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/mutation/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/mutation/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/query/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/query/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/web3api.build.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/web3api.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/expected/output.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/icon.png create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/link.svg create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/test.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/test.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/package.json create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/mutation/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/mutation/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/query/index.ts create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/query/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.build.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.meta.yaml create mode 100644 packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/001-sanity/.gitignore create mode 100644 packages/test-cases/cases/cli/api/deploy/001-sanity/package.json create mode 100644 packages/test-cases/cases/cli/api/deploy/001-sanity/src/query/index.ts create mode 100644 packages/test-cases/cases/cli/api/deploy/001-sanity/src/query/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.build.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.deploy.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/002-no-ext/.gitignore create mode 100644 packages/test-cases/cases/cli/api/deploy/002-no-ext/package.json create mode 100644 packages/test-cases/cases/cli/api/deploy/002-no-ext/src/query/index.ts create mode 100644 packages/test-cases/cases/cli/api/deploy/002-no-ext/src/query/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.build.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.deploy.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/003-invalid-config/.gitignore create mode 100644 packages/test-cases/cases/cli/api/deploy/003-invalid-config/package.json create mode 100644 packages/test-cases/cases/cli/api/deploy/003-invalid-config/src/query/index.ts create mode 100644 packages/test-cases/cases/cli/api/deploy/003-invalid-config/src/query/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.build.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.deploy.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/004-fail-between/.gitignore create mode 100644 packages/test-cases/cases/cli/api/deploy/004-fail-between/package.json create mode 100644 packages/test-cases/cases/cli/api/deploy/004-fail-between/src/query/index.ts create mode 100644 packages/test-cases/cases/cli/api/deploy/004-fail-between/src/query/schema.graphql create mode 100644 packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.build.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.deploy.yaml create mode 100644 packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.yaml diff --git a/packages/cli/src/__tests__/e2e/build.spec.ts b/packages/cli/src/__tests__/e2e/build.spec.ts index 83b1e1c490..e25a31253d 100644 --- a/packages/cli/src/__tests__/e2e/build.spec.ts +++ b/packages/cli/src/__tests__/e2e/build.spec.ts @@ -19,7 +19,7 @@ Options: `; describe("e2e tests for build command", () => { - const testCaseRoot = path.join(GetPathToCliTestFiles(), "api/build"); + const testCaseRoot = path.join(GetPathToCliTestFiles(), "api/build-cmd"); const testCases = fs.readdirSync(testCaseRoot, { withFileTypes: true }) .filter((dirent) => dirent.isDirectory()) diff --git a/packages/cli/src/__tests__/e2e/deploy.spec.ts b/packages/cli/src/__tests__/e2e/deploy.spec.ts index 945153e071..c8193e2074 100644 --- a/packages/cli/src/__tests__/e2e/deploy.spec.ts +++ b/packages/cli/src/__tests__/e2e/deploy.spec.ts @@ -1,19 +1,19 @@ import { clearStyle, w3Cli } from "./utils"; +import { loadDeployManifest } from "../../lib"; import { initTestEnvironment, - runCLI, stopTestEnvironment, + runCLI, + stopTestEnvironment, } from "@web3api/test-env-js"; -import path from "path"; +import { GetPathToCliTestFiles } from "@web3api/test-cases"; import axios from "axios"; import { Web3ApiClient } from "@web3api/client-js"; import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; import { Wallet } from "ethers"; import yaml from "js-yaml"; +import path from "path"; import fs from "fs"; -import { loadDeployManifest } from "../../lib"; - -const projectRoot = path.resolve(__dirname, "../project/"); const HELP = ` w3 deploy [options] @@ -24,7 +24,16 @@ Options: -v, --verbose Verbose output (default: false) `; +const testCaseRoot = path.join(GetPathToCliTestFiles(), "api/deploy"); + const testCases = + fs.readdirSync(testCaseRoot, { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => dirent.name); + const getTestCaseDir = (index: number) => + path.join(testCaseRoot, testCases[index]); + const setup = async (domainNames: string[]) => { + const projectRoot = getTestCaseDir(0); const { ethereum } = await initTestEnvironment(); const { data } = await axios.get("http://localhost:4040/deploy-ens"); @@ -101,7 +110,7 @@ describe("e2e tests for deploy command", () => { await runCLI( { args: ["build", "-v"], - cwd: projectRoot, + cwd: getTestCaseDir(0), cli: w3Cli, }, ); @@ -115,7 +124,7 @@ describe("e2e tests for deploy command", () => { const { exitCode: code, stdout: output, stderr: error } = await runCLI( { args: ["deploy", "--help"], - cwd: projectRoot, + cwd: getTestCaseDir(0), cli: w3Cli, }, ); @@ -129,7 +138,7 @@ describe("e2e tests for deploy command", () => { const { exitCode: code, stdout: output } = await runCLI( { args: ["deploy"], - cwd: projectRoot, + cwd: getTestCaseDir(0), cli: w3Cli, }, ); @@ -152,27 +161,22 @@ describe("e2e tests for deploy command", () => { }); test("Throws and stops chain if error is found", async () => { - const { exitCode: code, stdout: output, stderr } = await runCLI( + const { exitCode: code, stdout: output } = await runCLI( { - args: ["deploy", "--manifest-file", "web3api-deploy-fail-between.yaml"], - cwd: projectRoot, + args: ["deploy", "--manifest-file", "web3api-deploy-no-ext.yaml"], + cwd: getTestCaseDir(1), cli: w3Cli, }, ); const sanitizedOutput = clearStyle(output); - const sanitizedErr = clearStyle(stderr); - expect(code).toEqual(1); + expect(code).toEqual(0); expect(sanitizedOutput).toContain( - "Successfully executed stage 'ipfs_deploy'" - ); - expect(sanitizedOutput).not.toContain( - "Successfully executed stage 'from_deploy2'" + "No manifest extension found in" ); - - expect(sanitizedErr).toContain( - "Failed to execute stage 'from_deploy'" + expect(sanitizedOutput).toContain( + "Successfully executed stage 'ipfs_test'" ); }); @@ -180,7 +184,7 @@ describe("e2e tests for deploy command", () => { const { exitCode: code, stderr } = await runCLI( { args: ["deploy", "--manifest-file", "web3api-deploy-invalid-config.yaml"], - cwd: projectRoot, + cwd: getTestCaseDir(2), cli: w3Cli, }, ); @@ -192,22 +196,27 @@ describe("e2e tests for deploy command", () => { }); test("Throws and stops chain if error is found", async () => { - const { exitCode: code, stdout: output } = await runCLI( + const { exitCode: code, stdout: output, stderr } = await runCLI( { - args: ["deploy", "--manifest-file", "web3api-deploy-no-ext.yaml"], - cwd: projectRoot, + args: ["deploy", "--manifest-file", "web3api-deploy-fail-between.yaml"], + cwd: getTestCaseDir(3), cli: w3Cli, }, ); const sanitizedOutput = clearStyle(output); + const sanitizedErr = clearStyle(stderr); - expect(code).toEqual(0); + expect(code).toEqual(1); expect(sanitizedOutput).toContain( - "No manifest extension found in" + "Successfully executed stage 'ipfs_deploy'" ); - expect(sanitizedOutput).toContain( - "Successfully executed stage 'ipfs_test'" + expect(sanitizedOutput).not.toContain( + "Successfully executed stage 'from_deploy2'" + ); + + expect(sanitizedErr).toContain( + "Failed to execute stage 'from_deploy'" ); }); }); diff --git a/packages/cli/src/__tests__/e2e/help.spec.ts b/packages/cli/src/__tests__/e2e/help.spec.ts index 79d28011ea..e55a42f595 100644 --- a/packages/cli/src/__tests__/e2e/help.spec.ts +++ b/packages/cli/src/__tests__/e2e/help.spec.ts @@ -1,4 +1,3 @@ -import path from "path"; import { clearStyle, w3Cli } from "./utils"; import { runCLI } from "@web3api/test-env-js"; diff --git a/packages/cli/src/__tests__/e2e/query.spec.ts b/packages/cli/src/__tests__/e2e/query.spec.ts index 852344b43f..a7184fb4c3 100644 --- a/packages/cli/src/__tests__/e2e/query.spec.ts +++ b/packages/cli/src/__tests__/e2e/query.spec.ts @@ -74,7 +74,7 @@ describe("e2e tests for query command", () => { expect(deployErr).toBe(""); await buildAndDeployApi({ - apiAbsPath: projectRoot, + apiAbsPath: testCaseRoot, ipfsProvider: ipfs, ethereumProvider: ethereum, ensRegistrarAddress: registrarAddress, diff --git a/packages/cli/src/__tests__/unit/docker.spec.ts b/packages/cli/src/__tests__/unit/docker.spec.ts index 38a799845c..2d130df302 100644 --- a/packages/cli/src/__tests__/unit/docker.spec.ts +++ b/packages/cli/src/__tests__/unit/docker.spec.ts @@ -19,7 +19,7 @@ describe("e2e tests for docker", () => { promises.push( runCLI({ args: ["build", "-v"], - cwd: path.join(GetPathToCliTestFiles(), "api/build/001-sanity"), + cwd: path.join(GetPathToCliTestFiles(), "api/build-cmd/001-sanity"), cli: w3Cli }).then((result: { exitCode: number; stdout: string; stderr: string }) => { const { exitCode, stderr } = result; diff --git a/packages/test-cases/cases/cli/api/build-cmd/.gitignore b/packages/test-cases/cases/cli/api/build-cmd/.gitignore new file mode 100644 index 0000000000..c795b054e5 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/.gitignore @@ -0,0 +1 @@ +build \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/build-cmd/001-sanity/expected/output.json b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/expected/output.json new file mode 100644 index 0000000000..9b1784b4d9 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/expected/output.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + "Artifacts written to ./build from the image `polywrap-build-env-", + "Manifest written to ./build/web3api.json", + "build/web3api.json" + ], + "exitCode": 0 +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/001-sanity/package.json b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/package.json new file mode 100644 index 0000000000..3b78e56fc8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/package.json @@ -0,0 +1,15 @@ +{ + "name": "@web3api/test-project", + "version": "0.0.1-prealpha.72", + "license": "MIT", + "private": true, + "scripts": { + "build": "w3 build" + }, + "dependencies": { + "@web3api/wasm-as": "0.0.1-prealpha.72" + }, + "devDependencies": { + "assemblyscript": "0.19.1" + } +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/mutation/index.ts b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/mutation/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/mutation/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/mutation/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/mutation/schema.graphql new file mode 100644 index 0000000000..82e1e7c1e8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/mutation/schema.graphql @@ -0,0 +1,5 @@ +type Mutation { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/query/index.ts b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/query/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/query/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/query/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/query/schema.graphql new file mode 100644 index 0000000000..7fc63dcc2c --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/src/query/schema.graphql @@ -0,0 +1,5 @@ +type Query { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/001-sanity/web3api.build.yaml b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/web3api.build.yaml new file mode 100644 index 0000000000..2cf967618b --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/web3api.build.yaml @@ -0,0 +1,6 @@ +format: 0.0.1-prealpha.2 +config: + node_version: "14.16.0" +linked_packages: + - name: "@web3api/wasm-as" + path: ../../../../../../wasm/as diff --git a/packages/test-cases/cases/cli/api/build-cmd/001-sanity/web3api.yaml b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/web3api.yaml new file mode 100644 index 0000000000..e7880e1e3a --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/001-sanity/web3api.yaml @@ -0,0 +1,11 @@ +format: 0.0.1-prealpha.7 +name: test-project +build: ./web3api.build.yaml +language: wasm/assemblyscript +modules: + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/test-cases/cases/cli/api/build-cmd/002-invalid-manifest-1/expected/output.json b/packages/test-cases/cases/cli/api/build-cmd/002-invalid-manifest-1/expected/output.json new file mode 100644 index 0000000000..d92ea5d141 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/002-invalid-manifest-1/expected/output.json @@ -0,0 +1,7 @@ +{ + "stdout": [ + "ENOENT: no such file or directory", + "wrong/schema.graphql" + ], + "exitCode": 1 +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/002-invalid-manifest-1/web3api.yaml b/packages/test-cases/cases/cli/api/build-cmd/002-invalid-manifest-1/web3api.yaml new file mode 100644 index 0000000000..87bca4ce8d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/002-invalid-manifest-1/web3api.yaml @@ -0,0 +1,15 @@ +format: 0.0.1-prealpha.1 +description: Invalid Manifest +repository: https://github.com +mutation: + schema: + file: ./src/wrong/schema.graphql + module: + language: wasm/assemblyscript + file: ./src/wrong/index.ts +query: + schema: + file: ./src/wrong/schema.graphql + module: + language: wasm/assemblyscript + file: ./src/wrong/index.ts diff --git a/packages/test-cases/cases/cli/api/build-cmd/003-invalid-manifest-2/expected/output.json b/packages/test-cases/cases/cli/api/build-cmd/003-invalid-manifest-2/expected/output.json new file mode 100644 index 0000000000..9e2fb2de8c --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/003-invalid-manifest-2/expected/output.json @@ -0,0 +1,4 @@ +{ + "stdout": "instance is not allowed to have the additional property \"wrong_mutation\"", + "exitCode": 1 +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/003-invalid-manifest-2/web3api.yaml b/packages/test-cases/cases/cli/api/build-cmd/003-invalid-manifest-2/web3api.yaml new file mode 100644 index 0000000000..a78cbf3b19 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/003-invalid-manifest-2/web3api.yaml @@ -0,0 +1,15 @@ +format: 0.0.1-prealpha.1 +description: Invalid Manifest +repository: https://github.com +wrong_mutation: + schema: + file: ./src/mutation/schema.graphql + module: + language: wasm/assemblyscript + file: ./src/mutation/index.ts +wrong_query: + schema: + file: ./src/query/schema.graphql + module: + language: wasm/assemblyscript + file: ./src/query/index.ts diff --git a/packages/test-cases/cases/cli/api/build-cmd/004-default-build/expected/output.json b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/expected/output.json new file mode 100644 index 0000000000..9b1784b4d9 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/expected/output.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + "Artifacts written to ./build from the image `polywrap-build-env-", + "Manifest written to ./build/web3api.json", + "build/web3api.json" + ], + "exitCode": 0 +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/004-default-build/package.json b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/package.json new file mode 100644 index 0000000000..3b78e56fc8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/package.json @@ -0,0 +1,15 @@ +{ + "name": "@web3api/test-project", + "version": "0.0.1-prealpha.72", + "license": "MIT", + "private": true, + "scripts": { + "build": "w3 build" + }, + "dependencies": { + "@web3api/wasm-as": "0.0.1-prealpha.72" + }, + "devDependencies": { + "assemblyscript": "0.19.1" + } +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/mutation/index.ts b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/mutation/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/mutation/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/mutation/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/mutation/schema.graphql new file mode 100644 index 0000000000..82e1e7c1e8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/mutation/schema.graphql @@ -0,0 +1,5 @@ +type Mutation { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/query/index.ts b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/query/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/query/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/query/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/query/schema.graphql new file mode 100644 index 0000000000..7fc63dcc2c --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/src/query/schema.graphql @@ -0,0 +1,5 @@ +type Query { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/004-default-build/web3api.yaml b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/web3api.yaml new file mode 100644 index 0000000000..9a25b251fc --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/004-default-build/web3api.yaml @@ -0,0 +1,10 @@ +format: 0.0.1-prealpha.7 +name: test-project +language: wasm/assemblyscript +modules: + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/expected/output.json b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/expected/output.json new file mode 100644 index 0000000000..9b1784b4d9 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/expected/output.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + "Artifacts written to ./build from the image `polywrap-build-env-", + "Manifest written to ./build/web3api.json", + "build/web3api.json" + ], + "exitCode": 0 +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/package.json b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/package.json new file mode 100644 index 0000000000..3b78e56fc8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/package.json @@ -0,0 +1,15 @@ +{ + "name": "@web3api/test-project", + "version": "0.0.1-prealpha.72", + "license": "MIT", + "private": true, + "scripts": { + "build": "w3 build" + }, + "dependencies": { + "@web3api/wasm-as": "0.0.1-prealpha.72" + }, + "devDependencies": { + "assemblyscript": "0.19.1" + } +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/mutation/index.ts b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/mutation/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/mutation/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/mutation/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/mutation/schema.graphql new file mode 100644 index 0000000000..82e1e7c1e8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/mutation/schema.graphql @@ -0,0 +1,5 @@ +type Mutation { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/query/index.ts b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/query/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/query/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/query/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/query/schema.graphql new file mode 100644 index 0000000000..7fc63dcc2c --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/src/query/schema.graphql @@ -0,0 +1,5 @@ +type Query { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/web3api.build.yaml b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/web3api.build.yaml new file mode 100644 index 0000000000..361bbbf549 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/web3api.build.yaml @@ -0,0 +1,9 @@ +format: 0.0.1-prealpha.2 +config: + node_version: "14.16.0" + include: + - ./src + - ./package.json +linked_packages: + - name: "@web3api/wasm-as" + path: ../../../../../../wasm/as diff --git a/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/web3api.yaml b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/web3api.yaml new file mode 100644 index 0000000000..04031150aa --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/005-default-dockerfile/web3api.yaml @@ -0,0 +1,11 @@ +format: 0.0.1-prealpha.2 +repository: https://github.com +language: wasm/assemblyscript +build: ./web3api.build.yaml +modules: + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/Dockerfile b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/Dockerfile new file mode 100644 index 0000000000..72d569b409 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/Dockerfile @@ -0,0 +1,45 @@ +FROM node:14.16.0-alpine as base + +RUN apk --no-cache --virtual build-dependencies add \ + bash \ + git \ + openssh \ + make \ + g++ + +WORKDIR /linked-packages + +COPY .w3/web3api/build/linked-packages/@web3api/wasm-as ./@web3api/wasm-as + +WORKDIR /project + +# Install deps in its own step, making rebuilds faster +# when just the Web3API schema & implementation files change +COPY package.json . +RUN npx json -I -f package.json -e "this.dependencies['@web3api/wasm-as']='../linked-packages/@web3api/wasm-as'" +RUN yarn + +# Copy all manifest files +COPY web3api.yaml . +COPY web3api.build.yaml . + +# Copy all source files +COPY ./src ./src +COPY ./package.json ./package.json + +# Build the module at src/mutation +RUN ./node_modules/.bin/asc src/mutation/w3/entry.ts \ + --path ./node_modules \ + --outFile ./build/mutation.wasm \ + --use abort=src/mutation/w3/entry/w3Abort \ + --optimize --debug --importMemory \ + --runtime stub \ + --runPasses asyncify +# Build the module at src/query +RUN ./node_modules/.bin/asc src/query/w3/entry.ts \ + --path ./node_modules \ + --outFile ./build/query.wasm \ + --use abort=src/query/w3/entry/w3Abort \ + --optimize --debug --importMemory \ + --runtime stub \ + --runPasses asyncify diff --git a/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/expected/output.json b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/expected/output.json new file mode 100644 index 0000000000..9b1784b4d9 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/expected/output.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + "Artifacts written to ./build from the image `polywrap-build-env-", + "Manifest written to ./build/web3api.json", + "build/web3api.json" + ], + "exitCode": 0 +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/package.json b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/package.json new file mode 100644 index 0000000000..3b78e56fc8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/package.json @@ -0,0 +1,15 @@ +{ + "name": "@web3api/test-project", + "version": "0.0.1-prealpha.72", + "license": "MIT", + "private": true, + "scripts": { + "build": "w3 build" + }, + "dependencies": { + "@web3api/wasm-as": "0.0.1-prealpha.72" + }, + "devDependencies": { + "assemblyscript": "0.19.1" + } +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/mutation/index.ts b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/mutation/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/mutation/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/mutation/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/mutation/schema.graphql new file mode 100644 index 0000000000..82e1e7c1e8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/mutation/schema.graphql @@ -0,0 +1,5 @@ +type Mutation { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/query/index.ts b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/query/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/query/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/query/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/query/schema.graphql new file mode 100644 index 0000000000..7fc63dcc2c --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/src/query/schema.graphql @@ -0,0 +1,5 @@ +type Query { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/web3api.build.yaml b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/web3api.build.yaml new file mode 100644 index 0000000000..97a68a1d65 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/web3api.build.yaml @@ -0,0 +1,11 @@ +format: 0.0.1-prealpha.2 +docker: + dockerfile: ./Dockerfile +config: + node_version: "14.16.0" + include: + - ./src + - ./package.json +linked_packages: + - name: "@web3api/wasm-as" + path: ../../../../../../wasm/as diff --git a/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/web3api.yaml b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/web3api.yaml new file mode 100644 index 0000000000..04031150aa --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/006-custom-dockerfile/web3api.yaml @@ -0,0 +1,11 @@ +format: 0.0.1-prealpha.2 +repository: https://github.com +language: wasm/assemblyscript +build: ./web3api.build.yaml +modules: + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/expected/output.json b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/expected/output.json new file mode 100644 index 0000000000..9b1784b4d9 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/expected/output.json @@ -0,0 +1,8 @@ +{ + "stdout": [ + "Artifacts written to ./build from the image `polywrap-build-env-", + "Manifest written to ./build/web3api.json", + "build/web3api.json" + ], + "exitCode": 0 +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/package.json b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/package.json new file mode 100644 index 0000000000..3b78e56fc8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/package.json @@ -0,0 +1,15 @@ +{ + "name": "@web3api/test-project", + "version": "0.0.1-prealpha.72", + "license": "MIT", + "private": true, + "scripts": { + "build": "w3 build" + }, + "dependencies": { + "@web3api/wasm-as": "0.0.1-prealpha.72" + }, + "devDependencies": { + "assemblyscript": "0.19.1" + } +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/mutation/index.ts b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/mutation/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/mutation/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/mutation/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/mutation/schema.graphql new file mode 100644 index 0000000000..82e1e7c1e8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/mutation/schema.graphql @@ -0,0 +1,5 @@ +type Mutation { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/query/index.ts b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/query/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/query/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/query/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/query/schema.graphql new file mode 100644 index 0000000000..7fc63dcc2c --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/src/query/schema.graphql @@ -0,0 +1,5 @@ +type Query { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/web3api.build.yaml b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/web3api.build.yaml new file mode 100644 index 0000000000..7da8616f8a --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/web3api.build.yaml @@ -0,0 +1,13 @@ +format: 0.0.1-prealpha.2 +config: + node_version: "14.16.0" + include: + - ./src + - ./package.json +linked_packages: + - name: "@web3api/wasm-as" + path: ../../../../../../wasm/as + filter: /\.(test|spec)\.(js|ts)$/gm + - name: "@web3api/ethereum-plugin-js" + path: ../../../../../../js/plugins/ethereum + filter: /\.(test|spec)\.(js|ts)$/gm diff --git a/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/web3api.yaml b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/web3api.yaml new file mode 100644 index 0000000000..04031150aa --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/007-linked-packages/web3api.yaml @@ -0,0 +1,11 @@ +format: 0.0.1-prealpha.2 +repository: https://github.com +language: wasm/assemblyscript +build: ./web3api.build.yaml +modules: + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/expected/output.json b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/expected/output.json new file mode 100644 index 0000000000..898b3f7156 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/expected/output.json @@ -0,0 +1,13 @@ +{ + "stdout": [ + "Artifacts written to ./build from the image `polywrap-build-env-", + "Manifest written to ./build/web3api.json", + "build/web3api.json", + "build/web3api.meta.json", + "build/meta/queries/test.graphql", + "build/meta/queries/test.json", + "build/meta/links/link.svg", + "build/meta/icon/icon.png" + ], + "exitCode": 0 +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/icon.png b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/icon.png new file mode 100644 index 0000000000..674be608c0 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/icon.png @@ -0,0 +1 @@ +test png \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/link.svg b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/link.svg new file mode 100644 index 0000000000..c3db003053 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/link.svg @@ -0,0 +1 @@ +test svg \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/test.graphql b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/test.graphql new file mode 100644 index 0000000000..d58413e806 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/test.graphql @@ -0,0 +1 @@ +test graphql \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/test.json b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/test.json new file mode 100644 index 0000000000..60f07047e9 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/meta/test.json @@ -0,0 +1 @@ +test json \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/package.json b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/package.json new file mode 100644 index 0000000000..3b78e56fc8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/package.json @@ -0,0 +1,15 @@ +{ + "name": "@web3api/test-project", + "version": "0.0.1-prealpha.72", + "license": "MIT", + "private": true, + "scripts": { + "build": "w3 build" + }, + "dependencies": { + "@web3api/wasm-as": "0.0.1-prealpha.72" + }, + "devDependencies": { + "assemblyscript": "0.19.1" + } +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/mutation/index.ts b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/mutation/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/mutation/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/mutation/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/mutation/schema.graphql new file mode 100644 index 0000000000..82e1e7c1e8 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/mutation/schema.graphql @@ -0,0 +1,5 @@ +type Mutation { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/query/index.ts b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/query/index.ts new file mode 100644 index 0000000000..6d5ba30c9d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/query/index.ts @@ -0,0 +1,5 @@ +import { Input_method } from "./w3"; + +export function method(input: Input_method): string { + return input.arg; +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/query/schema.graphql b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/query/schema.graphql new file mode 100644 index 0000000000..7fc63dcc2c --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/src/query/schema.graphql @@ -0,0 +1,5 @@ +type Query { + method( + arg: String! + ): String! +} diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.build.yaml b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.build.yaml new file mode 100644 index 0000000000..2cf967618b --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.build.yaml @@ -0,0 +1,6 @@ +format: 0.0.1-prealpha.2 +config: + node_version: "14.16.0" +linked_packages: + - name: "@web3api/wasm-as" + path: ../../../../../../wasm/as diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.meta.yaml b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.meta.yaml new file mode 100644 index 0000000000..02ef3b9873 --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.meta.yaml @@ -0,0 +1,19 @@ +format: 0.0.1-prealpha.3 +displayName: Test Name +subtext: test subtext +description: test description +tags: + - test + - another-tag + - test2 +repository: https://github.com/test/test +icon: ./meta/icon.png +links: + - name: test link + icon: ./meta/link.svg + url: http://link.com/path +queries: + - name: test query + description: test description + query: ./meta/test.graphql + vars: ./meta/test.json diff --git a/packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.yaml b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.yaml new file mode 100644 index 0000000000..3bc116805d --- /dev/null +++ b/packages/test-cases/cases/cli/api/build-cmd/008-metadata/web3api.yaml @@ -0,0 +1,12 @@ +format: 0.0.1-prealpha.7 +name: test-project +language: wasm/assemblyscript +meta: ./web3api.meta.yaml +build: ./web3api.build.yaml +modules: + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/test-cases/cases/cli/api/deploy/001-sanity/.gitignore b/packages/test-cases/cases/cli/api/deploy/001-sanity/.gitignore new file mode 100644 index 0000000000..c795b054e5 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/001-sanity/.gitignore @@ -0,0 +1 @@ +build \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/deploy/001-sanity/package.json b/packages/test-cases/cases/cli/api/deploy/001-sanity/package.json new file mode 100644 index 0000000000..25e322ff1e --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/001-sanity/package.json @@ -0,0 +1,18 @@ +{ + "name": "@web3api/test-project", + "version": "0.0.1-prealpha.72", + "license": "MIT", + "private": true, + "scripts": { + "build": "w3 build", + "deploy": "w3 deploy", + "test:env:up": "w3 test-env up", + "test:env:down": "w3 test-env down" + }, + "dependencies": { + "@web3api/wasm-as": "0.0.1-prealpha.72" + }, + "devDependencies": { + "assemblyscript": "0.19.1" + } +} diff --git a/packages/test-cases/cases/cli/api/deploy/001-sanity/src/query/index.ts b/packages/test-cases/cases/cli/api/deploy/001-sanity/src/query/index.ts new file mode 100644 index 0000000000..0b5ae11277 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/001-sanity/src/query/index.ts @@ -0,0 +1,5 @@ +import { Input_get } from "./w3"; + +export function get(input: Input_get): string { + return "foo"; +} diff --git a/packages/test-cases/cases/cli/api/deploy/001-sanity/src/query/schema.graphql b/packages/test-cases/cases/cli/api/deploy/001-sanity/src/query/schema.graphql new file mode 100644 index 0000000000..260bc478f2 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/001-sanity/src/query/schema.graphql @@ -0,0 +1,3 @@ +type Query { + get: String! +} diff --git a/packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.build.yaml b/packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.build.yaml new file mode 100644 index 0000000000..ecef0619bf --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.build.yaml @@ -0,0 +1,6 @@ +format: 0.0.1-prealpha.2 +config: + node_version: "14.16.0" +linked_packages: + - name: "@web3api/wasm-as" + path: ../../../../../wasm/as diff --git a/packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.deploy.yaml b/packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.deploy.yaml new file mode 100644 index 0000000000..e1da00e826 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.deploy.yaml @@ -0,0 +1,26 @@ +format: 0.0.1-prealpha.1 +stages: + ipfs_deploy: + package: ipfs + uri: fs/./build + from_deploy: + package: ens + depends_on: ipfs_deploy + config: + domainName: test1.eth + provider: 'http://localhost:8545' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' + from_deploy2: + package: ens + depends_on: ipfs_deploy + config: + domainName: test2.eth + provider: 'http://localhost:8545' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' + from_uri: + package: ens + uri: ipfs/QmVdDR6QtigTt38Xwpj2Ki73X1AyZn5WRCreBCJq1CEtpF + config: + domainName: test3.eth + provider: 'http://localhost:8545' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' diff --git a/packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.yaml b/packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.yaml new file mode 100644 index 0000000000..e6ec3f2c87 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/001-sanity/web3api.yaml @@ -0,0 +1,9 @@ +format: 0.0.1-prealpha.8 +name: deploy-sanity +build: ./web3api.build.yaml +deploy: ./web3api.deploy.yaml +language: wasm/assemblyscript +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/test-cases/cases/cli/api/deploy/002-no-ext/.gitignore b/packages/test-cases/cases/cli/api/deploy/002-no-ext/.gitignore new file mode 100644 index 0000000000..c795b054e5 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/002-no-ext/.gitignore @@ -0,0 +1 @@ +build \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/deploy/002-no-ext/package.json b/packages/test-cases/cases/cli/api/deploy/002-no-ext/package.json new file mode 100644 index 0000000000..25e322ff1e --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/002-no-ext/package.json @@ -0,0 +1,18 @@ +{ + "name": "@web3api/test-project", + "version": "0.0.1-prealpha.72", + "license": "MIT", + "private": true, + "scripts": { + "build": "w3 build", + "deploy": "w3 deploy", + "test:env:up": "w3 test-env up", + "test:env:down": "w3 test-env down" + }, + "dependencies": { + "@web3api/wasm-as": "0.0.1-prealpha.72" + }, + "devDependencies": { + "assemblyscript": "0.19.1" + } +} diff --git a/packages/test-cases/cases/cli/api/deploy/002-no-ext/src/query/index.ts b/packages/test-cases/cases/cli/api/deploy/002-no-ext/src/query/index.ts new file mode 100644 index 0000000000..0b5ae11277 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/002-no-ext/src/query/index.ts @@ -0,0 +1,5 @@ +import { Input_get } from "./w3"; + +export function get(input: Input_get): string { + return "foo"; +} diff --git a/packages/test-cases/cases/cli/api/deploy/002-no-ext/src/query/schema.graphql b/packages/test-cases/cases/cli/api/deploy/002-no-ext/src/query/schema.graphql new file mode 100644 index 0000000000..260bc478f2 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/002-no-ext/src/query/schema.graphql @@ -0,0 +1,3 @@ +type Query { + get: String! +} diff --git a/packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.build.yaml b/packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.build.yaml new file mode 100644 index 0000000000..ecef0619bf --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.build.yaml @@ -0,0 +1,6 @@ +format: 0.0.1-prealpha.2 +config: + node_version: "14.16.0" +linked_packages: + - name: "@web3api/wasm-as" + path: ../../../../../wasm/as diff --git a/packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.deploy.yaml b/packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.deploy.yaml new file mode 100644 index 0000000000..11b28ba091 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.deploy.yaml @@ -0,0 +1,7 @@ +format: 0.0.1-prealpha.1 +stages: + ipfs_test: + package: ipfs-test + uri: fs/./build + config: + foo: bar \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.yaml b/packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.yaml new file mode 100644 index 0000000000..33629a3184 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/002-no-ext/web3api.yaml @@ -0,0 +1,9 @@ +format: 0.0.1-prealpha.8 +name: deploy-no-ext +build: ./web3api.build.yaml +deploy: ./web3api.deploy.yaml +language: wasm/assemblyscript +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/test-cases/cases/cli/api/deploy/003-invalid-config/.gitignore b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/.gitignore new file mode 100644 index 0000000000..c795b054e5 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/.gitignore @@ -0,0 +1 @@ +build \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/deploy/003-invalid-config/package.json b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/package.json new file mode 100644 index 0000000000..25e322ff1e --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/package.json @@ -0,0 +1,18 @@ +{ + "name": "@web3api/test-project", + "version": "0.0.1-prealpha.72", + "license": "MIT", + "private": true, + "scripts": { + "build": "w3 build", + "deploy": "w3 deploy", + "test:env:up": "w3 test-env up", + "test:env:down": "w3 test-env down" + }, + "dependencies": { + "@web3api/wasm-as": "0.0.1-prealpha.72" + }, + "devDependencies": { + "assemblyscript": "0.19.1" + } +} diff --git a/packages/test-cases/cases/cli/api/deploy/003-invalid-config/src/query/index.ts b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/src/query/index.ts new file mode 100644 index 0000000000..0b5ae11277 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/src/query/index.ts @@ -0,0 +1,5 @@ +import { Input_get } from "./w3"; + +export function get(input: Input_get): string { + return "foo"; +} diff --git a/packages/test-cases/cases/cli/api/deploy/003-invalid-config/src/query/schema.graphql b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/src/query/schema.graphql new file mode 100644 index 0000000000..260bc478f2 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/src/query/schema.graphql @@ -0,0 +1,3 @@ +type Query { + get: String! +} diff --git a/packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.build.yaml b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.build.yaml new file mode 100644 index 0000000000..ecef0619bf --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.build.yaml @@ -0,0 +1,6 @@ +format: 0.0.1-prealpha.2 +config: + node_version: "14.16.0" +linked_packages: + - name: "@web3api/wasm-as" + path: ../../../../../wasm/as diff --git a/packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.deploy.yaml b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.deploy.yaml new file mode 100644 index 0000000000..6586dc8bb7 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.deploy.yaml @@ -0,0 +1,12 @@ +format: 0.0.1-prealpha.1 +stages: + ipfs_deploy: + package: ipfs + uri: fs/./build + from_deploy: + package: ens + depends_on: ipfs_deploy + config: + domainName: true + provider: 'http://localhost:8545' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.yaml b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.yaml new file mode 100644 index 0000000000..142bcee8ca --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/003-invalid-config/web3api.yaml @@ -0,0 +1,9 @@ +format: 0.0.1-prealpha.8 +name: deploy-invalid-config +build: ./web3api.build.yaml +deploy: ./web3api.deploy.yaml +language: wasm/assemblyscript +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/test-cases/cases/cli/api/deploy/004-fail-between/.gitignore b/packages/test-cases/cases/cli/api/deploy/004-fail-between/.gitignore new file mode 100644 index 0000000000..c795b054e5 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/004-fail-between/.gitignore @@ -0,0 +1 @@ +build \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/deploy/004-fail-between/package.json b/packages/test-cases/cases/cli/api/deploy/004-fail-between/package.json new file mode 100644 index 0000000000..25e322ff1e --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/004-fail-between/package.json @@ -0,0 +1,18 @@ +{ + "name": "@web3api/test-project", + "version": "0.0.1-prealpha.72", + "license": "MIT", + "private": true, + "scripts": { + "build": "w3 build", + "deploy": "w3 deploy", + "test:env:up": "w3 test-env up", + "test:env:down": "w3 test-env down" + }, + "dependencies": { + "@web3api/wasm-as": "0.0.1-prealpha.72" + }, + "devDependencies": { + "assemblyscript": "0.19.1" + } +} diff --git a/packages/test-cases/cases/cli/api/deploy/004-fail-between/src/query/index.ts b/packages/test-cases/cases/cli/api/deploy/004-fail-between/src/query/index.ts new file mode 100644 index 0000000000..0b5ae11277 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/004-fail-between/src/query/index.ts @@ -0,0 +1,5 @@ +import { Input_get } from "./w3"; + +export function get(input: Input_get): string { + return "foo"; +} diff --git a/packages/test-cases/cases/cli/api/deploy/004-fail-between/src/query/schema.graphql b/packages/test-cases/cases/cli/api/deploy/004-fail-between/src/query/schema.graphql new file mode 100644 index 0000000000..260bc478f2 --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/004-fail-between/src/query/schema.graphql @@ -0,0 +1,3 @@ +type Query { + get: String! +} diff --git a/packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.build.yaml b/packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.build.yaml new file mode 100644 index 0000000000..ecef0619bf --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.build.yaml @@ -0,0 +1,6 @@ +format: 0.0.1-prealpha.2 +config: + node_version: "14.16.0" +linked_packages: + - name: "@web3api/wasm-as" + path: ../../../../../wasm/as diff --git a/packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.deploy.yaml b/packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.deploy.yaml new file mode 100644 index 0000000000..a424c340bc --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.deploy.yaml @@ -0,0 +1,19 @@ +format: 0.0.1-prealpha.1 +stages: + ipfs_deploy: + package: ipfs + uri: fs/./build + from_deploy: + package: ens + depends_on: ipfs_deploy + config: + domainName: test1.eth + provider: 'foo' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' + from_deploy2: + package: ens + depends_on: ipfs_deploy + config: + domainName: test2.eth + provider: 'http://localhost:8545' + ensRegistryAddress: '0x9b1f7F645351AF3631a656421eD2e40f2802E6c0' \ No newline at end of file diff --git a/packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.yaml b/packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.yaml new file mode 100644 index 0000000000..8c4f89474d --- /dev/null +++ b/packages/test-cases/cases/cli/api/deploy/004-fail-between/web3api.yaml @@ -0,0 +1,9 @@ +format: 0.0.1-prealpha.8 +name: deploy-fail-between +build: ./web3api.build.yaml +deploy: ./web3api.deploy.yaml +language: wasm/assemblyscript +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts From 7c87bf223b6635f1d6318d7d1a619f798b3aabb2 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 26 Apr 2022 00:24:05 -0600 Subject: [PATCH 38/41] fix dependencies:link script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b64e7a4c01..8f8a6d8352 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "reset": "yarn clean && yarn && yarn build", "clean": "npx rimraf ./**/node_modules ./**/yarn.lock ./**/build ./**/coverage ./**/.w3", "dependencies:install": "cd dependencies && yarn", - "dependencies:link": "cd packages/schema/bind && yarn link && cd ../../../dependencies && yarn link @web3api/schema-bind", + "dependencies:link": "cd packages/schema/bind && (yarn unlink || true) && yarn link && cd ../../../dependencies && yarn link @web3api/schema-bind", "preinstall": "yarn dependencies:install", "build": "yarn build:core && yarn dependencies:link && yarn build:plugins && yarn build:client && yarn build:cli", "build:core": "lerna run build --no-private --ignore @web3api/*-plugin-js --ignore @web3api/cli* --ignore @web3api/react", From 46c4be8a1a01c16d034e6ca9a398fbc8811bb5e8 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 26 Apr 2022 00:32:20 -0600 Subject: [PATCH 39/41] fix cli plugin tests --- packages/cli/src/__tests__/e2e/plugin.spec.ts | 2 +- .../expected/build-artifacts/schema.graphql | 393 ++++++++++++++++++ .../build-artifacts/web3api.plugin.json | 15 + .../expected/build-artifacts/schema.graphql | 291 +++++++++++++ .../build-artifacts/web3api.plugin.json | 11 + .../expected/build-artifacts/schema.graphql | 64 +++ .../build-artifacts/web3api.plugin.json | 15 + .../expected/build-artifacts/schema.graphql | 64 +++ .../build-artifacts/web3api.plugin.json | 15 + .../expected/build-artifacts/schema.graphql | 80 ++++ .../build-artifacts/web3api.plugin.json | 15 + 11 files changed, 964 insertions(+), 1 deletion(-) create mode 100644 packages/test-cases/cases/cli/plugin/codegen/001-sanity/expected/build-artifacts/schema.graphql create mode 100644 packages/test-cases/cases/cli/plugin/codegen/001-sanity/expected/build-artifacts/web3api.plugin.json create mode 100644 packages/test-cases/cases/cli/plugin/codegen/002-single-module/expected/build-artifacts/schema.graphql create mode 100644 packages/test-cases/cases/cli/plugin/codegen/002-single-module/expected/build-artifacts/web3api.plugin.json create mode 100644 packages/test-cases/cases/cli/plugin/codegen/003-env-shared/expected/build-artifacts/schema.graphql create mode 100644 packages/test-cases/cases/cli/plugin/codegen/003-env-shared/expected/build-artifacts/web3api.plugin.json create mode 100644 packages/test-cases/cases/cli/plugin/codegen/004-env-different/expected/build-artifacts/schema.graphql create mode 100644 packages/test-cases/cases/cli/plugin/codegen/004-env-different/expected/build-artifacts/web3api.plugin.json create mode 100644 packages/test-cases/cases/cli/plugin/codegen/005-env-sanitization/expected/build-artifacts/schema.graphql create mode 100644 packages/test-cases/cases/cli/plugin/codegen/005-env-sanitization/expected/build-artifacts/web3api.plugin.json diff --git a/packages/cli/src/__tests__/e2e/plugin.spec.ts b/packages/cli/src/__tests__/e2e/plugin.spec.ts index f137b18d88..17604a4b60 100644 --- a/packages/cli/src/__tests__/e2e/plugin.spec.ts +++ b/packages/cli/src/__tests__/e2e/plugin.spec.ts @@ -136,7 +136,7 @@ ${HELP}`); const expectedBuildResult = compareSync( `${testCaseDir}/build`, - `${testCaseDir}/expected/build`, + `${testCaseDir}/expected/build-artifacts`, { compareContent: true } ); diff --git a/packages/test-cases/cases/cli/plugin/codegen/001-sanity/expected/build-artifacts/schema.graphql b/packages/test-cases/cases/cli/plugin/codegen/001-sanity/expected/build-artifacts/schema.graphql new file mode 100644 index 0000000000..8b62cd22f5 --- /dev/null +++ b/packages/test-cases/cases/cli/plugin/codegen/001-sanity/expected/build-artifacts/schema.graphql @@ -0,0 +1,393 @@ +### Web3API Header START ### +scalar UInt +scalar UInt8 +scalar UInt16 +scalar UInt32 +scalar Int +scalar Int8 +scalar Int16 +scalar Int32 +scalar Bytes +scalar BigInt +scalar BigNumber +scalar JSON +scalar Map + +directive @imported( + uri: String! + namespace: String! + nativeType: String! +) on OBJECT | ENUM + +directive @imports( + types: [String!]! +) on OBJECT + +directive @capability( + type: String! + uri: String! + namespace: String! +) repeatable on OBJECT + +directive @enabled_interface on OBJECT + +directive @annotate(type: String!) on FIELD + +### Web3API Header END ### + +type Mutation @imports( + types: [ + "Ethereum_Mutation", + "Ethereum_Connection", + "Ethereum_TxOverrides", + "Ethereum_TxResponse", + "Ethereum_Access", + "Ethereum_TxReceipt", + "Ethereum_Log", + "Ethereum_TxRequest" + ] +) { + method( + arg: UInt32! + ): String! +} + +type Query @imports( + types: [ + "Ethereum_Query", + "Ethereum_Connection", + "Ethereum_TxOverrides", + "Ethereum_StaticTxResult", + "Ethereum_TxRequest", + "Ethereum_TxReceipt", + "Ethereum_Log", + "Ethereum_EventNotification", + "Ethereum_Network" + ] +) { + method( + str: String! + optStr: String + ): Object! +} + +type QueryEnv { + arg1: String! +} + +type Object { + u: UInt! + array: [Boolean!]! + bytes: Bytes +} + +### Imported Queries START ### + +type Ethereum_Mutation @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Mutation" +) { + callContractMethod( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + txOverrides: Ethereum_TxOverrides + ): Ethereum_TxResponse! + + callContractMethodAndWait( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + txOverrides: Ethereum_TxOverrides + ): Ethereum_TxReceipt! + + sendTransaction( + tx: Ethereum_TxRequest! + connection: Ethereum_Connection + ): Ethereum_TxResponse! + + sendTransactionAndWait( + tx: Ethereum_TxRequest! + connection: Ethereum_Connection + ): Ethereum_TxReceipt! + + deployContract( + abi: String! + bytecode: String! + args: [String!] + connection: Ethereum_Connection + ): String! + + signMessage( + message: String! + connection: Ethereum_Connection + ): String! + + sendRPC( + method: String! + params: [String!]! + connection: Ethereum_Connection + ): String +} + +type Ethereum_Query @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Query" +) { + callContractView( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + ): String! + + callContractStatic( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + txOverrides: Ethereum_TxOverrides + ): Ethereum_StaticTxResult! + + getBalance( + address: String! + blockTag: BigInt + connection: Ethereum_Connection + ): BigInt! + + encodeParams( + types: [String!]! + values: [String!]! + ): String! + + encodeFunction( + method: String! + args: [String!] + ): String! + + solidityPack( + types: [String!]! + values: [String!]! + ): String! + + solidityKeccak256( + types: [String!]! + values: [String!]! + ): String! + + soliditySha256( + types: [String!]! + values: [String!]! + ): String! + + getSignerAddress( + connection: Ethereum_Connection + ): String! + + getSignerBalance( + blockTag: BigInt + connection: Ethereum_Connection + ): BigInt! + + getSignerTransactionCount( + blockTag: BigInt + connection: Ethereum_Connection + ): BigInt! + + getGasPrice( + connection: Ethereum_Connection + ): BigInt! + + estimateTransactionGas( + tx: Ethereum_TxRequest! + connection: Ethereum_Connection + ): BigInt! + + estimateContractCallGas( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + txOverrides: Ethereum_TxOverrides + ): BigInt! + + checkAddress( + address: String! + ): Boolean! + + toWei( + eth: String! + ): BigInt! + + toEth( + wei: BigInt! + ): String! + + awaitTransaction( + txHash: String! + confirmations: UInt32! + timeout: UInt32! + connection: Ethereum_Connection + ): Ethereum_TxReceipt! + + waitForEvent( + address: String! + event: String! + args: [String!] + timeout: UInt32 + connection: Ethereum_Connection + ): Ethereum_EventNotification! + + getNetwork( + connection: Ethereum_Connection + ): Ethereum_Network! +} + +### Imported Queries END ### + +### Imported Objects START ### + +type Ethereum_Connection @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Connection" +) { + node: String + networkNameOrChainId: String +} + +type Ethereum_TxOverrides @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "TxOverrides" +) { + gasLimit: BigInt + gasPrice: BigInt + value: BigInt +} + +type Ethereum_TxResponse @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "TxResponse" +) { + hash: String! + to: String + from: String! + nonce: UInt32! + gasLimit: BigInt! + gasPrice: BigInt + data: String! + value: BigInt! + chainId: BigInt! + blockNumber: BigInt + blockHash: String + timestamp: UInt32 + confirmations: UInt32! + raw: String + r: String + s: String + v: UInt32 + type: UInt32 + accessList: [Ethereum_Access!] +} + +type Ethereum_Access @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Access" +) { + address: String! + storageKeys: [String!]! +} + +type Ethereum_TxReceipt @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "TxReceipt" +) { + to: String! + from: String! + contractAddress: String! + transactionIndex: UInt32! + root: String + gasUsed: BigInt! + logsBloom: String! + transactionHash: String! + logs: [Ethereum_Log!]! + blockNumber: BigInt! + blockHash: String! + confirmations: UInt32! + cumulativeGasUsed: BigInt! + effectiveGasPrice: BigInt! + byzantium: Boolean! + type: UInt32! + status: UInt32 +} + +type Ethereum_Log @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Log" +) { + blockNumber: BigInt! + blockHash: String! + transactionIndex: UInt32! + removed: Boolean! + address: String! + data: String! + topics: [String!]! + transactionHash: String! + logIndex: UInt32! +} + +type Ethereum_TxRequest @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "TxRequest" +) { + to: String + from: String + nonce: UInt32 + gasLimit: BigInt + gasPrice: BigInt + data: String + value: BigInt + chainId: BigInt + type: UInt32 +} + +type Ethereum_StaticTxResult @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "StaticTxResult" +) { + result: String! + error: Boolean! +} + +type Ethereum_EventNotification @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "EventNotification" +) { + data: String! + address: String! + log: Ethereum_Log! +} + +type Ethereum_Network @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Network" +) { + name: String! + chainId: BigInt! + ensAddress: String +} + +### Imported Objects END ### diff --git a/packages/test-cases/cases/cli/plugin/codegen/001-sanity/expected/build-artifacts/web3api.plugin.json b/packages/test-cases/cases/cli/plugin/codegen/001-sanity/expected/build-artifacts/web3api.plugin.json new file mode 100644 index 0000000000..8fbbffeebe --- /dev/null +++ b/packages/test-cases/cases/cli/plugin/codegen/001-sanity/expected/build-artifacts/web3api.plugin.json @@ -0,0 +1,15 @@ +{ + "format": "0.0.1-prealpha.2", + "name": "Test", + "language": "plugin/typescript", + "modules": { + "mutation": { + "schema": "./src/mutation/schema.graphql", + "module": "./src/mutation/index.ts" + }, + "query": { + "schema": "./src/query/schema.graphql", + "module": "./src/query/index.ts" + } + } +} \ No newline at end of file diff --git a/packages/test-cases/cases/cli/plugin/codegen/002-single-module/expected/build-artifacts/schema.graphql b/packages/test-cases/cases/cli/plugin/codegen/002-single-module/expected/build-artifacts/schema.graphql new file mode 100644 index 0000000000..c44f5b7567 --- /dev/null +++ b/packages/test-cases/cases/cli/plugin/codegen/002-single-module/expected/build-artifacts/schema.graphql @@ -0,0 +1,291 @@ +### Web3API Header START ### +scalar UInt +scalar UInt8 +scalar UInt16 +scalar UInt32 +scalar Int +scalar Int8 +scalar Int16 +scalar Int32 +scalar Bytes +scalar BigInt +scalar BigNumber +scalar JSON +scalar Map + +directive @imported( + uri: String! + namespace: String! + nativeType: String! +) on OBJECT | ENUM + +directive @imports( + types: [String!]! +) on OBJECT + +directive @capability( + type: String! + uri: String! + namespace: String! +) repeatable on OBJECT + +directive @enabled_interface on OBJECT + +directive @annotate(type: String!) on FIELD + +### Web3API Header END ### + +type Query @imports( + types: [ + "Ethereum_Query", + "Ethereum_Connection", + "Ethereum_TxOverrides", + "Ethereum_StaticTxResult", + "Ethereum_TxRequest", + "Ethereum_TxReceipt", + "Ethereum_Log", + "Ethereum_EventNotification", + "Ethereum_Network" + ] +) { + method( + str: String! + optStr: String + ): Object! +} + +type QueryEnv { + arg1: String! +} + +type Object { + u: UInt! + array: [Boolean!]! + bytes: Bytes +} + +### Imported Queries START ### + +type Ethereum_Query @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Query" +) { + callContractView( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + ): String! + + callContractStatic( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + txOverrides: Ethereum_TxOverrides + ): Ethereum_StaticTxResult! + + getBalance( + address: String! + blockTag: BigInt + connection: Ethereum_Connection + ): BigInt! + + encodeParams( + types: [String!]! + values: [String!]! + ): String! + + encodeFunction( + method: String! + args: [String!] + ): String! + + solidityPack( + types: [String!]! + values: [String!]! + ): String! + + solidityKeccak256( + types: [String!]! + values: [String!]! + ): String! + + soliditySha256( + types: [String!]! + values: [String!]! + ): String! + + getSignerAddress( + connection: Ethereum_Connection + ): String! + + getSignerBalance( + blockTag: BigInt + connection: Ethereum_Connection + ): BigInt! + + getSignerTransactionCount( + blockTag: BigInt + connection: Ethereum_Connection + ): BigInt! + + getGasPrice( + connection: Ethereum_Connection + ): BigInt! + + estimateTransactionGas( + tx: Ethereum_TxRequest! + connection: Ethereum_Connection + ): BigInt! + + estimateContractCallGas( + address: String! + method: String! + args: [String!] + connection: Ethereum_Connection + txOverrides: Ethereum_TxOverrides + ): BigInt! + + checkAddress( + address: String! + ): Boolean! + + toWei( + eth: String! + ): BigInt! + + toEth( + wei: BigInt! + ): String! + + awaitTransaction( + txHash: String! + confirmations: UInt32! + timeout: UInt32! + connection: Ethereum_Connection + ): Ethereum_TxReceipt! + + waitForEvent( + address: String! + event: String! + args: [String!] + timeout: UInt32 + connection: Ethereum_Connection + ): Ethereum_EventNotification! + + getNetwork( + connection: Ethereum_Connection + ): Ethereum_Network! +} + +### Imported Queries END ### + +### Imported Objects START ### + +type Ethereum_Connection @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Connection" +) { + node: String + networkNameOrChainId: String +} + +type Ethereum_TxOverrides @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "TxOverrides" +) { + gasLimit: BigInt + gasPrice: BigInt + value: BigInt +} + +type Ethereum_StaticTxResult @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "StaticTxResult" +) { + result: String! + error: Boolean! +} + +type Ethereum_TxRequest @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "TxRequest" +) { + to: String + from: String + nonce: UInt32 + gasLimit: BigInt + gasPrice: BigInt + data: String + value: BigInt + chainId: BigInt + type: UInt32 +} + +type Ethereum_TxReceipt @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "TxReceipt" +) { + to: String! + from: String! + contractAddress: String! + transactionIndex: UInt32! + root: String + gasUsed: BigInt! + logsBloom: String! + transactionHash: String! + logs: [Ethereum_Log!]! + blockNumber: BigInt! + blockHash: String! + confirmations: UInt32! + cumulativeGasUsed: BigInt! + effectiveGasPrice: BigInt! + byzantium: Boolean! + type: UInt32! + status: UInt32 +} + +type Ethereum_Log @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Log" +) { + blockNumber: BigInt! + blockHash: String! + transactionIndex: UInt32! + removed: Boolean! + address: String! + data: String! + topics: [String!]! + transactionHash: String! + logIndex: UInt32! +} + +type Ethereum_EventNotification @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "EventNotification" +) { + data: String! + address: String! + log: Ethereum_Log! +} + +type Ethereum_Network @imported( + uri: "ens/ethereum.web3api.eth", + namespace: "Ethereum", + nativeType: "Network" +) { + name: String! + chainId: BigInt! + ensAddress: String +} + +### Imported Objects END ### diff --git a/packages/test-cases/cases/cli/plugin/codegen/002-single-module/expected/build-artifacts/web3api.plugin.json b/packages/test-cases/cases/cli/plugin/codegen/002-single-module/expected/build-artifacts/web3api.plugin.json new file mode 100644 index 0000000000..6147308120 --- /dev/null +++ b/packages/test-cases/cases/cli/plugin/codegen/002-single-module/expected/build-artifacts/web3api.plugin.json @@ -0,0 +1,11 @@ +{ + "format": "0.0.1-prealpha.2", + "name": "Test", + "language": "plugin/typescript", + "modules": { + "query": { + "schema": "./src/query/schema.graphql", + "module": "./src/query/index.ts" + } + } +} \ No newline at end of file diff --git a/packages/test-cases/cases/cli/plugin/codegen/003-env-shared/expected/build-artifacts/schema.graphql b/packages/test-cases/cases/cli/plugin/codegen/003-env-shared/expected/build-artifacts/schema.graphql new file mode 100644 index 0000000000..d6c7da7f79 --- /dev/null +++ b/packages/test-cases/cases/cli/plugin/codegen/003-env-shared/expected/build-artifacts/schema.graphql @@ -0,0 +1,64 @@ +### Web3API Header START ### +scalar UInt +scalar UInt8 +scalar UInt16 +scalar UInt32 +scalar Int +scalar Int8 +scalar Int16 +scalar Int32 +scalar Bytes +scalar BigInt +scalar BigNumber +scalar JSON +scalar Map + +directive @imported( + uri: String! + namespace: String! + nativeType: String! +) on OBJECT | ENUM + +directive @imports( + types: [String!]! +) on OBJECT + +directive @capability( + type: String! + uri: String! + namespace: String! +) repeatable on OBJECT + +directive @enabled_interface on OBJECT + +directive @annotate(type: String!) on FIELD + +### Web3API Header END ### + +type Mutation { + method( + arg: UInt32! + ): String! +} + +type Query { + method( + str: String! + ): String! +} + +type QueryEnv { + arg1: String! +} + +type MutationEnv { + arg1: String! +} + +### Imported Queries START ### + +### Imported Queries END ### + +### Imported Objects START ### + +### Imported Objects END ### diff --git a/packages/test-cases/cases/cli/plugin/codegen/003-env-shared/expected/build-artifacts/web3api.plugin.json b/packages/test-cases/cases/cli/plugin/codegen/003-env-shared/expected/build-artifacts/web3api.plugin.json new file mode 100644 index 0000000000..8fbbffeebe --- /dev/null +++ b/packages/test-cases/cases/cli/plugin/codegen/003-env-shared/expected/build-artifacts/web3api.plugin.json @@ -0,0 +1,15 @@ +{ + "format": "0.0.1-prealpha.2", + "name": "Test", + "language": "plugin/typescript", + "modules": { + "mutation": { + "schema": "./src/mutation/schema.graphql", + "module": "./src/mutation/index.ts" + }, + "query": { + "schema": "./src/query/schema.graphql", + "module": "./src/query/index.ts" + } + } +} \ No newline at end of file diff --git a/packages/test-cases/cases/cli/plugin/codegen/004-env-different/expected/build-artifacts/schema.graphql b/packages/test-cases/cases/cli/plugin/codegen/004-env-different/expected/build-artifacts/schema.graphql new file mode 100644 index 0000000000..4ebc7ea55c --- /dev/null +++ b/packages/test-cases/cases/cli/plugin/codegen/004-env-different/expected/build-artifacts/schema.graphql @@ -0,0 +1,64 @@ +### Web3API Header START ### +scalar UInt +scalar UInt8 +scalar UInt16 +scalar UInt32 +scalar Int +scalar Int8 +scalar Int16 +scalar Int32 +scalar Bytes +scalar BigInt +scalar BigNumber +scalar JSON +scalar Map + +directive @imported( + uri: String! + namespace: String! + nativeType: String! +) on OBJECT | ENUM + +directive @imports( + types: [String!]! +) on OBJECT + +directive @capability( + type: String! + uri: String! + namespace: String! +) repeatable on OBJECT + +directive @enabled_interface on OBJECT + +directive @annotate(type: String!) on FIELD + +### Web3API Header END ### + +type Mutation { + method( + arg: UInt32! + ): String! +} + +type Query { + method( + str: String! + ): String! +} + +type QueryEnv { + queryArg: String! +} + +type MutationEnv { + mutationArg: String! +} + +### Imported Queries START ### + +### Imported Queries END ### + +### Imported Objects START ### + +### Imported Objects END ### diff --git a/packages/test-cases/cases/cli/plugin/codegen/004-env-different/expected/build-artifacts/web3api.plugin.json b/packages/test-cases/cases/cli/plugin/codegen/004-env-different/expected/build-artifacts/web3api.plugin.json new file mode 100644 index 0000000000..8fbbffeebe --- /dev/null +++ b/packages/test-cases/cases/cli/plugin/codegen/004-env-different/expected/build-artifacts/web3api.plugin.json @@ -0,0 +1,15 @@ +{ + "format": "0.0.1-prealpha.2", + "name": "Test", + "language": "plugin/typescript", + "modules": { + "mutation": { + "schema": "./src/mutation/schema.graphql", + "module": "./src/mutation/index.ts" + }, + "query": { + "schema": "./src/query/schema.graphql", + "module": "./src/query/index.ts" + } + } +} \ No newline at end of file diff --git a/packages/test-cases/cases/cli/plugin/codegen/005-env-sanitization/expected/build-artifacts/schema.graphql b/packages/test-cases/cases/cli/plugin/codegen/005-env-sanitization/expected/build-artifacts/schema.graphql new file mode 100644 index 0000000000..d994814aed --- /dev/null +++ b/packages/test-cases/cases/cli/plugin/codegen/005-env-sanitization/expected/build-artifacts/schema.graphql @@ -0,0 +1,80 @@ +### Web3API Header START ### +scalar UInt +scalar UInt8 +scalar UInt16 +scalar UInt32 +scalar Int +scalar Int8 +scalar Int16 +scalar Int32 +scalar Bytes +scalar BigInt +scalar BigNumber +scalar JSON +scalar Map + +directive @imported( + uri: String! + namespace: String! + nativeType: String! +) on OBJECT | ENUM + +directive @imports( + types: [String!]! +) on OBJECT + +directive @capability( + type: String! + uri: String! + namespace: String! +) repeatable on OBJECT + +directive @enabled_interface on OBJECT + +directive @annotate(type: String!) on FIELD + +### Web3API Header END ### + +type Mutation { + sanitizeEnv( + env: MutationClientEnv! + ): MutationEnv! + + method( + arg: UInt32! + ): String! +} + +type Query { + sanitizeEnv( + env: QueryClientEnv! + ): QueryEnv! + + method( + str: String! + ): String! +} + +type QueryClientEnv { + bar: UInt32! +} + +type QueryEnv { + queryArg: String! +} + +type MutationClientEnv { + foo: UInt32! +} + +type MutationEnv { + mutationArg: String! +} + +### Imported Queries START ### + +### Imported Queries END ### + +### Imported Objects START ### + +### Imported Objects END ### diff --git a/packages/test-cases/cases/cli/plugin/codegen/005-env-sanitization/expected/build-artifacts/web3api.plugin.json b/packages/test-cases/cases/cli/plugin/codegen/005-env-sanitization/expected/build-artifacts/web3api.plugin.json new file mode 100644 index 0000000000..8fbbffeebe --- /dev/null +++ b/packages/test-cases/cases/cli/plugin/codegen/005-env-sanitization/expected/build-artifacts/web3api.plugin.json @@ -0,0 +1,15 @@ +{ + "format": "0.0.1-prealpha.2", + "name": "Test", + "language": "plugin/typescript", + "modules": { + "mutation": { + "schema": "./src/mutation/schema.graphql", + "module": "./src/mutation/index.ts" + }, + "query": { + "schema": "./src/query/schema.graphql", + "module": "./src/query/index.ts" + } + } +} \ No newline at end of file From e15e463cb4288264204b5c91a8b2ad41c270b6d5 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 26 Apr 2022 12:25:44 -0600 Subject: [PATCH 40/41] fix deploy tests --- packages/cli/src/__tests__/e2e/deploy.spec.ts | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/cli/src/__tests__/e2e/deploy.spec.ts b/packages/cli/src/__tests__/e2e/deploy.spec.ts index c8193e2074..976884c867 100644 --- a/packages/cli/src/__tests__/e2e/deploy.spec.ts +++ b/packages/cli/src/__tests__/e2e/deploy.spec.ts @@ -107,14 +107,17 @@ const setup = async (domainNames: string[]) => { describe("e2e tests for deploy command", () => { beforeAll(async () => { await setup(["test1", "test2", "test3"]) - await runCLI( - { - args: ["build", "-v"], - cwd: getTestCaseDir(0), - cli: w3Cli, - }, - ); - }) + + for (let i = 0; i < testCases.length; ++i) { + await runCLI( + { + args: ["build", "-v"], + cwd: getTestCaseDir(i), + cli: w3Cli, + }, + ); + } + }); afterAll(async () => { await stopTestEnvironment(); @@ -163,7 +166,7 @@ describe("e2e tests for deploy command", () => { test("Throws and stops chain if error is found", async () => { const { exitCode: code, stdout: output } = await runCLI( { - args: ["deploy", "--manifest-file", "web3api-deploy-no-ext.yaml"], + args: ["deploy"], cwd: getTestCaseDir(1), cli: w3Cli, }, @@ -183,7 +186,7 @@ describe("e2e tests for deploy command", () => { test("Throws if manifest ext exists and config property is invalid", async () => { const { exitCode: code, stderr } = await runCLI( { - args: ["deploy", "--manifest-file", "web3api-deploy-invalid-config.yaml"], + args: ["deploy"], cwd: getTestCaseDir(2), cli: w3Cli, }, @@ -198,7 +201,7 @@ describe("e2e tests for deploy command", () => { test("Throws and stops chain if error is found", async () => { const { exitCode: code, stdout: output, stderr } = await runCLI( { - args: ["deploy", "--manifest-file", "web3api-deploy-fail-between.yaml"], + args: ["deploy"], cwd: getTestCaseDir(3), cli: w3Cli, }, From a68db09e1837ba6504702eb785988cb893affd32 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Tue, 26 Apr 2022 13:00:48 -0600 Subject: [PATCH 41/41] fixed client test --- packages/js/client/src/__tests__/Web3ApiClient.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts index 800af89405..5a02d1e8e0 100644 --- a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts +++ b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts @@ -2193,6 +2193,7 @@ scalar Int16 scalar Int32 scalar Bytes scalar BigInt +scalar BigNumber scalar JSON scalar Map