diff --git a/.eslintrc.js b/.eslintrc.js index b9c9526e99..196b1fba94 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -132,44 +132,6 @@ module.exports = { { files: ["*.json"], extends: ["plugin:json/recommended"], - }, - { - files: ["*.graphql"], - plugins: ["@graphql-eslint"], - parser: "@graphql-eslint/eslint-plugin", - rules: { - "function-call-argument-newline": ["error"], - "@graphql-eslint/avoid-typename-prefix": ["warn"], - "@graphql-eslint/no-hashtag-description": ["off"], - "@graphql-eslint/require-deprecation-reason": ["error"], - "@graphql-eslint/no-case-insensitive-enum-values-duplicates": ["error"], - "@graphql-eslint/description-style": ["warn", {"style":"inline"}], - "@graphql-eslint/avoid-duplicate-fields": ["error"], - "@graphql-eslint/naming-convention": ["error", - { - "FieldDefinition":"camelCase", - "InputObjectTypeDefinition":"PascalCase", - "EnumValueDefinition":"UPPER_CASE", - "InputValueDefinition":"camelCase", - "ObjectTypeDefinition":"PascalCase", - "InterfaceTypeDefinition":"PascalCase", - "EnumTypeDefinition":"PascalCase", - "UnionTypeDefinition":"PascalCase", - "ScalarTypeDefinition":"PascalCase", - "OperationDefinition":"PascalCase", - "FragmentDefinition":"PascalCase", - "QueryDefinition":"camelCase", - "leadingUnderscore":"forbid", - "trailingUnderscore":"forbid" - }], - "@graphql-eslint/possible-type-extension": ["error"], - "@graphql-eslint/unique-operation-name": ["error"], - "@graphql-eslint/unique-directive-names": ["error"], - "@graphql-eslint/unique-enum-value-names": ["error"], - "@graphql-eslint/unique-field-definition-names": ["error"], - "@graphql-eslint/unique-input-field-names": ["error"], - "@graphql-eslint/unique-type-names": ["error"], - } } ] }; diff --git a/package.json b/package.json index 72bb1d88d0..024e34d268 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,10 @@ "clean": "npx rimraf ./**/node_modules ./**/yarn.lock ./**/build ./**/coverage ./**/.w3", "install:dependencies": "cd dependencies && yarn", "preinstall": "yarn install:dependencies", - "build": "yarn build:core && yarn build:plugins && yarn build:client && yarn build:cli", + "build": "yarn build:core && yarn build:plugins && yarn build:client && yarn build:cli && yarn build:plugins:migrate", "build:core": "lerna run build --no-private --ignore @web3api/*-plugin-js --ignore @web3api/cli* --ignore @web3api/react", "build:plugins": "lerna run build --scope @web3api/*-plugin-js --concurrency 1", + "build:plugins:migrate": "lerna run build:migrate --scope @web3api/*-plugin-js --concurrency 1", "build:client": "lerna run build --scope @web3api/client-js --scope @web3api/react", "build:cli": "lerna run build --scope @web3api/cli", "lint": "lerna run lint", @@ -51,7 +52,6 @@ "eslint-plugin-prettier": "3.4.0", "prettier": "2.2.1", "graphql": "15.5.0", - "@graphql-eslint/eslint-plugin": "1.0.1", "eslint-plugin-json": "3.0.0" }, "resolutions": { diff --git a/packages/cli/src/__tests__/e2e/plugin.spec.ts b/packages/cli/src/__tests__/e2e/plugin.spec.ts index 1c7ad8f7f1..1a367b7761 100644 --- a/packages/cli/src/__tests__/e2e/plugin.spec.ts +++ b/packages/cli/src/__tests__/e2e/plugin.spec.ts @@ -113,11 +113,10 @@ ${HELP}`); `); const expectedTypesResult = compareSync( - `${projectRoot}/src/w3`, + `${projectRoot}/src`, `${projectRoot}/expected-types`, { compareContent: true } ); - expect(expectedTypesResult.differences).toBe(0); const expectedBuildResult = compareSync( diff --git a/packages/cli/src/__tests__/plugin/.gitignore b/packages/cli/src/__tests__/plugin/.gitignore new file mode 100644 index 0000000000..718901b655 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/.gitignore @@ -0,0 +1,3 @@ +!expected-types/w3 +!expected-types/query/w3 +!expected-types/mutation/w3 diff --git a/packages/cli/src/__tests__/plugin/expected-build/schema.graphql b/packages/cli/src/__tests__/plugin/expected-build/schema.graphql index 3ea1eb0d47..8b62cd22f5 100644 --- a/packages/cli/src/__tests__/plugin/expected-build/schema.graphql +++ b/packages/cli/src/__tests__/plugin/expected-build/schema.graphql @@ -35,29 +35,24 @@ directive @annotate(type: String!) on FIELD ### Web3API Header END ### -type Query @imports( +type Mutation @imports( types: [ - "Ethereum_Query", + "Ethereum_Mutation", "Ethereum_Connection", "Ethereum_TxOverrides", - "Ethereum_StaticTxResult", - "Ethereum_TxRequest", + "Ethereum_TxResponse", + "Ethereum_Access", "Ethereum_TxReceipt", "Ethereum_Log", - "Ethereum_EventNotification", - "Ethereum_Network", - "Ethereum_Mutation", - "Ethereum_TxResponse", - "Ethereum_Access" + "Ethereum_TxRequest" ] ) { method( - str: String! - optStr: String - ): Object! + arg: UInt32! + ): String! } -type Mutation @imports( +type Query @imports( types: [ "Ethereum_Query", "Ethereum_Connection", @@ -67,15 +62,17 @@ type Mutation @imports( "Ethereum_TxReceipt", "Ethereum_Log", "Ethereum_EventNotification", - "Ethereum_Network", - "Ethereum_Mutation", - "Ethereum_TxResponse", - "Ethereum_Access" + "Ethereum_Network" ] ) { method( - arg: UInt32! - ): String! + str: String! + optStr: String + ): Object! +} + +type QueryEnv { + arg1: String! } type Object { @@ -86,6 +83,56 @@ type Object { ### 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", @@ -200,56 +247,6 @@ type Ethereum_Query @imported( ): Ethereum_Network! } -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 -} - ### Imported Queries END ### ### Imported Objects START ### @@ -273,29 +270,39 @@ type Ethereum_TxOverrides @imported( value: BigInt } -type Ethereum_StaticTxResult @imported( +type Ethereum_TxResponse @imported( uri: "ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "StaticTxResult" + nativeType: "TxResponse" ) { - result: String! - error: Boolean! + 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_TxRequest @imported( +type Ethereum_Access @imported( uri: "ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "TxRequest" + nativeType: "Access" ) { - to: String - from: String - nonce: UInt32 - gasLimit: BigInt - gasPrice: BigInt - data: String - value: BigInt - chainId: BigInt - type: UInt32 + address: String! + storageKeys: [String!]! } type Ethereum_TxReceipt @imported( @@ -338,59 +345,49 @@ type Ethereum_Log @imported( logIndex: UInt32! } -type Ethereum_EventNotification @imported( +type Ethereum_TxRequest @imported( uri: "ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "EventNotification" + nativeType: "TxRequest" ) { - data: String! - address: String! - log: Ethereum_Log! + to: String + from: String + nonce: UInt32 + gasLimit: BigInt + gasPrice: BigInt + data: String + value: BigInt + chainId: BigInt + type: UInt32 } -type Ethereum_Network @imported( +type Ethereum_StaticTxResult @imported( uri: "ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "Network" + nativeType: "StaticTxResult" ) { - name: String! - chainId: BigInt! - ensAddress: String + result: String! + error: Boolean! } -type Ethereum_TxResponse @imported( +type Ethereum_EventNotification @imported( uri: "ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "TxResponse" + nativeType: "EventNotification" ) { - 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!] + address: String! + log: Ethereum_Log! } -type Ethereum_Access @imported( +type Ethereum_Network @imported( uri: "ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "Access" + nativeType: "Network" ) { - address: String! - storageKeys: [String!]! + name: String! + chainId: BigInt! + ensAddress: String } ### Imported Objects END ### diff --git a/packages/cli/src/__tests__/plugin/expected-build/web3api.plugin.json b/packages/cli/src/__tests__/plugin/expected-build/web3api.plugin.json index 6bc8673f5f..8fbbffeebe 100644 --- a/packages/cli/src/__tests__/plugin/expected-build/web3api.plugin.json +++ b/packages/cli/src/__tests__/plugin/expected-build/web3api.plugin.json @@ -1,5 +1,15 @@ { - "format": "0.0.1-prealpha.1", + "format": "0.0.1-prealpha.2", + "name": "Test", "language": "plugin/typescript", - "schema": "./schema.graphql" + "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/cli/src/__tests__/plugin/expected-types/index.ts b/packages/cli/src/__tests__/plugin/expected-types/index.ts index 905246e513..b455821d3e 100644 --- a/packages/cli/src/__tests__/plugin/expected-types/index.ts +++ b/packages/cli/src/__tests__/plugin/expected-types/index.ts @@ -1,5 +1,3 @@ -export * as Query from "./query"; -export * as Mutation from "./mutation"; -export * from "./types"; -export * from "./schema"; -export * from "./manifest"; +// TIP: All user-defined code lives in the module folders (./query, ./mutation) + +export * from "./w3"; diff --git a/packages/cli/src/__tests__/plugin/expected-types/mutation.ts b/packages/cli/src/__tests__/plugin/expected-types/mutation.ts deleted file mode 100644 index 5002cf89c1..0000000000 --- a/packages/cli/src/__tests__/plugin/expected-types/mutation.ts +++ /dev/null @@ -1,35 +0,0 @@ -// @ts-noCheck -import { - UInt, - UInt8, - UInt16, - UInt32, - Int, - Int8, - Int16, - Int32, - Bytes, - BigInt, - BigNumber, - Json, - String, - Boolean -} from "./types"; -import * as Types from "./types"; - -import { - Client, - PluginModule, - MaybeAsync -} from "@web3api/core-js"; - -export interface Input_method extends Record { - arg: UInt32; -} - -export interface Module extends PluginModule { - method( - input: Input_method, - client: Client - ): MaybeAsync; -} diff --git a/packages/cli/src/__tests__/plugin/expected-types/mutation/index.ts b/packages/cli/src/__tests__/plugin/expected-types/mutation/index.ts new file mode 100644 index 0000000000..409a9dea15 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/expected-types/mutation/index.ts @@ -0,0 +1,16 @@ +import { Client } from "@web3api/core-js"; +import { + Module, + Input_method +} from "./w3"; + +export interface MutationConfig extends Record { + +} + +export class Mutation extends Module { + + public method(_input: Input_method, _client: Client): string { + return "foo"; + } +} \ No newline at end of file diff --git a/packages/cli/src/__tests__/plugin/expected-types/mutation/schema.graphql b/packages/cli/src/__tests__/plugin/expected-types/mutation/schema.graphql new file mode 100644 index 0000000000..abe9db84a0 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/expected-types/mutation/schema.graphql @@ -0,0 +1,7 @@ +#import { Mutation } into Ethereum from "ens/ethereum.web3api.eth" + +type Mutation { + method( + arg: UInt32! + ): String! +} diff --git a/packages/cli/src/__tests__/plugin/expected-types/mutation/w3/index.ts b/packages/cli/src/__tests__/plugin/expected-types/mutation/w3/index.ts new file mode 100644 index 0000000000..efe3c2530f --- /dev/null +++ b/packages/cli/src/__tests__/plugin/expected-types/mutation/w3/index.ts @@ -0,0 +1,7 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/client-js"; diff --git a/packages/cli/src/__tests__/plugin/expected-types/mutation/w3/module.ts b/packages/cli/src/__tests__/plugin/expected-types/mutation/w3/module.ts new file mode 100644 index 0000000000..2f6e0bece6 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/expected-types/mutation/w3/module.ts @@ -0,0 +1,26 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import * as Types from "./types"; + +import { + Client, + PluginModule, + MaybeAsync +} from "@web3api/core-js"; + +export interface Input_method extends Record { + arg: Types.UInt32; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule< + TConfig +> { + + abstract method( + input: Input_method, + client: Client + ): MaybeAsync; +} diff --git a/packages/cli/src/__tests__/plugin/expected-types/mutation/w3/types.ts b/packages/cli/src/__tests__/plugin/expected-types/mutation/w3/types.ts new file mode 100644 index 0000000000..fa63f0ebb4 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/expected-types/mutation/w3/types.ts @@ -0,0 +1,270 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +// @ts-ignore +import * as Types from "./"; + +// @ts-ignore +import { + Client, + InvokeApiResult +} from "@web3api/core-js"; + +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type BigNumber = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; + +/// Envs START /// +/// Envs END /// + +/// Objects START /// +/// Objects END /// + +/// Enums START /// +/// Enums END /// + +/// Imported Objects START /// + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_Connection { + node?: Types.String | null; + networkNameOrChainId?: Types.String | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_TxOverrides { + gasLimit?: Types.BigInt | null; + gasPrice?: Types.BigInt | null; + value?: Types.BigInt | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_TxResponse { + hash: Types.String; + to?: Types.String | null; + from: Types.String; + nonce: Types.UInt32; + gasLimit: Types.BigInt; + gasPrice?: Types.BigInt | null; + data: Types.String; + value: Types.BigInt; + chainId: Types.BigInt; + blockNumber?: Types.BigInt | null; + blockHash?: Types.String | null; + timestamp?: Types.UInt32 | null; + confirmations: Types.UInt32; + raw?: Types.String | null; + r?: Types.String | null; + s?: Types.String | null; + v?: Types.UInt32 | null; + type?: Types.UInt32 | null; + accessList?: Array | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_Access { + address: Types.String; + storageKeys: Array; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_TxReceipt { + to: Types.String; + from: Types.String; + contractAddress: Types.String; + transactionIndex: Types.UInt32; + root?: Types.String | null; + gasUsed: Types.BigInt; + logsBloom: Types.String; + transactionHash: Types.String; + logs: Array; + blockNumber: Types.BigInt; + blockHash: Types.String; + confirmations: Types.UInt32; + cumulativeGasUsed: Types.BigInt; + effectiveGasPrice: Types.BigInt; + byzantium: Types.Boolean; + type: Types.UInt32; + status?: Types.UInt32 | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_Log { + blockNumber: Types.BigInt; + blockHash: Types.String; + transactionIndex: Types.UInt32; + removed: Types.Boolean; + address: Types.String; + data: Types.String; + topics: Array; + transactionHash: Types.String; + logIndex: Types.UInt32; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_TxRequest { + to?: Types.String | null; + from?: Types.String | null; + nonce?: Types.UInt32 | null; + gasLimit?: Types.BigInt | null; + gasPrice?: Types.BigInt | null; + data?: Types.String | null; + value?: Types.BigInt | null; + chainId?: Types.BigInt | null; + type?: Types.UInt32 | null; +} + +/// Imported Objects END /// + +/// Imported Queries START /// + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Mutation_Input_callContractMethod extends Record { + address: Types.String; + method: Types.String; + args?: Array | null; + connection?: Types.Ethereum_Connection | null; + txOverrides?: Types.Ethereum_TxOverrides | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Mutation_Input_callContractMethodAndWait extends Record { + address: Types.String; + method: Types.String; + args?: Array | null; + connection?: Types.Ethereum_Connection | null; + txOverrides?: Types.Ethereum_TxOverrides | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Mutation_Input_sendTransaction extends Record { + tx: Types.Ethereum_TxRequest; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Mutation_Input_sendTransactionAndWait extends Record { + tx: Types.Ethereum_TxRequest; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Mutation_Input_deployContract extends Record { + abi: Types.String; + bytecode: Types.String; + args?: Array | null; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Mutation_Input_signMessage extends Record { + message: Types.String; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Mutation_Input_sendRPC extends Record { + method: Types.String; + params: Array; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export const Ethereum_Mutation = { + callContractMethod: async ( + input: Ethereum_Mutation_Input_callContractMethod, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "mutation", + method: "callContractMethod", + input + }); + }, + + callContractMethodAndWait: async ( + input: Ethereum_Mutation_Input_callContractMethodAndWait, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "mutation", + method: "callContractMethodAndWait", + input + }); + }, + + sendTransaction: async ( + input: Ethereum_Mutation_Input_sendTransaction, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "mutation", + method: "sendTransaction", + input + }); + }, + + sendTransactionAndWait: async ( + input: Ethereum_Mutation_Input_sendTransactionAndWait, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "mutation", + method: "sendTransactionAndWait", + input + }); + }, + + deployContract: async ( + input: Ethereum_Mutation_Input_deployContract, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "mutation", + method: "deployContract", + input + }); + }, + + signMessage: async ( + input: Ethereum_Mutation_Input_signMessage, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "mutation", + method: "signMessage", + input + }); + }, + + sendRPC: async ( + input: Ethereum_Mutation_Input_sendRPC, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "mutation", + method: "sendRPC", + input + }); + } +} + +/// Imported Queries END /// diff --git a/packages/cli/src/__tests__/plugin/expected-types/query.ts b/packages/cli/src/__tests__/plugin/expected-types/query.ts deleted file mode 100644 index 74649444b0..0000000000 --- a/packages/cli/src/__tests__/plugin/expected-types/query.ts +++ /dev/null @@ -1,36 +0,0 @@ -// @ts-noCheck -import { - UInt, - UInt8, - UInt16, - UInt32, - Int, - Int8, - Int16, - Int32, - Bytes, - BigInt, - BigNumber, - Json, - String, - Boolean -} from "./types"; -import * as Types from "./types"; - -import { - Client, - PluginModule, - MaybeAsync -} from "@web3api/core-js"; - -export interface Input_method extends Record { - str: String; - optStr?: String | null; -} - -export interface Module extends PluginModule { - method( - input: Input_method, - client: Client - ): MaybeAsync; -} diff --git a/packages/cli/src/__tests__/plugin/expected-types/query/index.ts b/packages/cli/src/__tests__/plugin/expected-types/query/index.ts new file mode 100644 index 0000000000..2631f7d387 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/expected-types/query/index.ts @@ -0,0 +1,21 @@ +import { Client } from "@web3api/core-js"; +import { + Module, + Object, + Input_method +} from "./w3"; + +export interface QueryConfig extends Record { + +} + +export class Query extends Module { + + public method(_input: Input_method, _client: Client): Object { + return { + u: 0, + array: [true], + bytes: null, + }; + } +} \ No newline at end of file diff --git a/packages/cli/src/__tests__/plugin/schema.graphql b/packages/cli/src/__tests__/plugin/expected-types/query/schema.graphql similarity index 52% rename from packages/cli/src/__tests__/plugin/schema.graphql rename to packages/cli/src/__tests__/plugin/expected-types/query/schema.graphql index 5909f564fa..ef7f0933cf 100644 --- a/packages/cli/src/__tests__/plugin/schema.graphql +++ b/packages/cli/src/__tests__/plugin/expected-types/query/schema.graphql @@ -1,4 +1,4 @@ -#import { Query, Mutation } into Ethereum from "ens/ethereum.web3api.eth" +#import { Query } into Ethereum from "ens/ethereum.web3api.eth" type Query { method( @@ -7,14 +7,12 @@ type Query { ): Object! } -type Mutation { - method( - arg: UInt32! - ): String! -} - type Object { u: UInt! array: [Boolean!]! bytes: Bytes } + +type Env { + arg1: String! +} diff --git a/packages/cli/src/__tests__/plugin/expected-types/query/w3/index.ts b/packages/cli/src/__tests__/plugin/expected-types/query/w3/index.ts new file mode 100644 index 0000000000..efe3c2530f --- /dev/null +++ b/packages/cli/src/__tests__/plugin/expected-types/query/w3/index.ts @@ -0,0 +1,7 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/client-js"; diff --git a/packages/cli/src/__tests__/plugin/expected-types/query/w3/module.ts b/packages/cli/src/__tests__/plugin/expected-types/query/w3/module.ts new file mode 100644 index 0000000000..1d6cb5ee75 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/expected-types/query/w3/module.ts @@ -0,0 +1,28 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import * as Types from "./types"; + +import { + Client, + PluginModule, + MaybeAsync +} from "@web3api/core-js"; + +export interface Input_method extends Record { + str: Types.String; + optStr?: Types.String | null; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule< + TConfig, + Types.QueryEnv +> { + + abstract method( + input: Input_method, + client: Client + ): MaybeAsync; +} diff --git a/packages/cli/src/__tests__/plugin/expected-types/query/w3/types.ts b/packages/cli/src/__tests__/plugin/expected-types/query/w3/types.ts new file mode 100644 index 0000000000..60db0dc649 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/expected-types/query/w3/types.ts @@ -0,0 +1,503 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +// @ts-ignore +import * as Types from "./"; + +// @ts-ignore +import { + Client, + InvokeApiResult +} from "@web3api/core-js"; + +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type BigNumber = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; + +/// Envs START /// +export interface QueryEnv extends Record { + arg1: Types.String; +} +/// Envs END /// + +/// Objects START /// +export interface Object { + u: Types.UInt; + array: Array; + bytes?: Types.Bytes | null; +} + +/// Objects END /// + +/// Enums START /// +/// Enums END /// + +/// Imported Objects START /// + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_Connection { + node?: Types.String | null; + networkNameOrChainId?: Types.String | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_TxOverrides { + gasLimit?: Types.BigInt | null; + gasPrice?: Types.BigInt | null; + value?: Types.BigInt | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_StaticTxResult { + result: Types.String; + error: Types.Boolean; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_TxRequest { + to?: Types.String | null; + from?: Types.String | null; + nonce?: Types.UInt32 | null; + gasLimit?: Types.BigInt | null; + gasPrice?: Types.BigInt | null; + data?: Types.String | null; + value?: Types.BigInt | null; + chainId?: Types.BigInt | null; + type?: Types.UInt32 | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_TxReceipt { + to: Types.String; + from: Types.String; + contractAddress: Types.String; + transactionIndex: Types.UInt32; + root?: Types.String | null; + gasUsed: Types.BigInt; + logsBloom: Types.String; + transactionHash: Types.String; + logs: Array; + blockNumber: Types.BigInt; + blockHash: Types.String; + confirmations: Types.UInt32; + cumulativeGasUsed: Types.BigInt; + effectiveGasPrice: Types.BigInt; + byzantium: Types.Boolean; + type: Types.UInt32; + status?: Types.UInt32 | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_Log { + blockNumber: Types.BigInt; + blockHash: Types.String; + transactionIndex: Types.UInt32; + removed: Types.Boolean; + address: Types.String; + data: Types.String; + topics: Array; + transactionHash: Types.String; + logIndex: Types.UInt32; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_EventNotification { + data: Types.String; + address: Types.String; + log: Types.Ethereum_Log; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export interface Ethereum_Network { + name: Types.String; + chainId: Types.BigInt; + ensAddress?: Types.String | null; +} + +/// Imported Objects END /// + +/// Imported Queries START /// + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_callContractView extends Record { + address: Types.String; + method: Types.String; + args?: Array | null; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_callContractStatic extends Record { + address: Types.String; + method: Types.String; + args?: Array | null; + connection?: Types.Ethereum_Connection | null; + txOverrides?: Types.Ethereum_TxOverrides | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_getBalance extends Record { + address: Types.String; + blockTag?: Types.BigInt | null; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_encodeParams extends Record { + types: Array; + values: Array; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_encodeFunction extends Record { + method: Types.String; + args?: Array | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_solidityPack extends Record { + types: Array; + values: Array; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_solidityKeccak256 extends Record { + types: Array; + values: Array; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_soliditySha256 extends Record { + types: Array; + values: Array; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_getSignerAddress extends Record { + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_getSignerBalance extends Record { + blockTag?: Types.BigInt | null; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_getSignerTransactionCount extends Record { + blockTag?: Types.BigInt | null; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_getGasPrice extends Record { + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_estimateTransactionGas extends Record { + tx: Types.Ethereum_TxRequest; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_estimateContractCallGas extends Record { + address: Types.String; + method: Types.String; + args?: Array | null; + connection?: Types.Ethereum_Connection | null; + txOverrides?: Types.Ethereum_TxOverrides | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_checkAddress extends Record { + address: Types.String; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_toWei extends Record { + eth: Types.String; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_toEth extends Record { + wei: Types.BigInt; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_awaitTransaction extends Record { + txHash: Types.String; + confirmations: Types.UInt32; + timeout: Types.UInt32; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_waitForEvent extends Record { + address: Types.String; + event: Types.String; + args?: Array | null; + timeout?: Types.UInt32 | null; + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +interface Ethereum_Query_Input_getNetwork extends Record { + connection?: Types.Ethereum_Connection | null; +} + +/* URI: "ens/ethereum.web3api.eth" */ +export const Ethereum_Query = { + callContractView: async ( + input: Ethereum_Query_Input_callContractView, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "callContractView", + input + }); + }, + + callContractStatic: async ( + input: Ethereum_Query_Input_callContractStatic, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "callContractStatic", + input + }); + }, + + getBalance: async ( + input: Ethereum_Query_Input_getBalance, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "getBalance", + input + }); + }, + + encodeParams: async ( + input: Ethereum_Query_Input_encodeParams, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "encodeParams", + input + }); + }, + + encodeFunction: async ( + input: Ethereum_Query_Input_encodeFunction, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "encodeFunction", + input + }); + }, + + solidityPack: async ( + input: Ethereum_Query_Input_solidityPack, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "solidityPack", + input + }); + }, + + solidityKeccak256: async ( + input: Ethereum_Query_Input_solidityKeccak256, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "solidityKeccak256", + input + }); + }, + + soliditySha256: async ( + input: Ethereum_Query_Input_soliditySha256, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "soliditySha256", + input + }); + }, + + getSignerAddress: async ( + input: Ethereum_Query_Input_getSignerAddress, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "getSignerAddress", + input + }); + }, + + getSignerBalance: async ( + input: Ethereum_Query_Input_getSignerBalance, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "getSignerBalance", + input + }); + }, + + getSignerTransactionCount: async ( + input: Ethereum_Query_Input_getSignerTransactionCount, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "getSignerTransactionCount", + input + }); + }, + + getGasPrice: async ( + input: Ethereum_Query_Input_getGasPrice, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "getGasPrice", + input + }); + }, + + estimateTransactionGas: async ( + input: Ethereum_Query_Input_estimateTransactionGas, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "estimateTransactionGas", + input + }); + }, + + estimateContractCallGas: async ( + input: Ethereum_Query_Input_estimateContractCallGas, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "estimateContractCallGas", + input + }); + }, + + checkAddress: async ( + input: Ethereum_Query_Input_checkAddress, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "checkAddress", + input + }); + }, + + toWei: async ( + input: Ethereum_Query_Input_toWei, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "toWei", + input + }); + }, + + toEth: async ( + input: Ethereum_Query_Input_toEth, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "toEth", + input + }); + }, + + awaitTransaction: async ( + input: Ethereum_Query_Input_awaitTransaction, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "awaitTransaction", + input + }); + }, + + waitForEvent: async ( + input: Ethereum_Query_Input_waitForEvent, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "waitForEvent", + input + }); + }, + + getNetwork: async ( + input: Ethereum_Query_Input_getNetwork, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/ethereum.web3api.eth", + module: "query", + method: "getNetwork", + input + }); + } +} + +/// Imported Queries END /// diff --git a/packages/cli/src/__tests__/plugin/expected-types/w3/index.ts b/packages/cli/src/__tests__/plugin/expected-types/w3/index.ts new file mode 100644 index 0000000000..6c0a9a1500 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/expected-types/w3/index.ts @@ -0,0 +1,6 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export * from "./schema"; +export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/cli/src/__tests__/plugin/expected-types/manifest.ts b/packages/cli/src/__tests__/plugin/expected-types/w3/manifest.ts similarity index 51% rename from packages/cli/src/__tests__/plugin/expected-types/manifest.ts rename to packages/cli/src/__tests__/plugin/expected-types/w3/manifest.ts index 5e193c285e..4d35c2182f 100644 --- a/packages/cli/src/__tests__/plugin/expected-types/manifest.ts +++ b/packages/cli/src/__tests__/plugin/expected-types/w3/manifest.ts @@ -1,10 +1,15 @@ -// @ts-noCheck +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +/* eslint-disable @typescript-eslint/no-unused-vars */ + import { schema } from "./"; +// @ts-ignore import { PluginPackageManifest, Uri } from "@web3api/core-js"; export const manifest: PluginPackageManifest = { schema, implements: [ ], -} +}; diff --git a/packages/cli/src/__tests__/plugin/expected-types/w3/plugin.ts b/packages/cli/src/__tests__/plugin/expected-types/w3/plugin.ts new file mode 100644 index 0000000000..8e8551fdff --- /dev/null +++ b/packages/cli/src/__tests__/plugin/expected-types/w3/plugin.ts @@ -0,0 +1,43 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; +import { Query, QueryConfig } from "../query"; +import { Mutation, MutationConfig } from "../mutation"; +import { manifest } from "./manifest"; + +export interface TestPluginConfigs { + query: QueryConfig; + mutation: MutationConfig; +} + +export class TestPlugin implements Plugin { + constructor(private _configs: TestPluginConfigs) { } + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + query: new Query(this._configs.query), + mutation: new Mutation(this._configs.mutation), + }; + } +} + +export const testPlugin: PluginFactory = ( + opts: TestPluginConfigs +) => { + return { + factory: () => new TestPlugin(opts), + manifest: manifest, + }; +}; + +export const plugin = testPlugin; diff --git a/packages/cli/src/__tests__/plugin/expected-types/schema.ts b/packages/cli/src/__tests__/plugin/expected-types/w3/schema.ts similarity index 96% rename from packages/cli/src/__tests__/plugin/expected-types/schema.ts rename to packages/cli/src/__tests__/plugin/expected-types/w3/schema.ts index 45e000666e..871621a86d 100644 --- a/packages/cli/src/__tests__/plugin/expected-types/schema.ts +++ b/packages/cli/src/__tests__/plugin/expected-types/w3/schema.ts @@ -1,3 +1,6 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + export const schema: string = `### Web3API Header START ### scalar UInt scalar UInt8 @@ -45,10 +48,7 @@ type Query @imports( "Ethereum_TxReceipt", "Ethereum_Log", "Ethereum_EventNotification", - "Ethereum_Network", - "Ethereum_Mutation", - "Ethereum_TxResponse", - "Ethereum_Access" + "Ethereum_Network" ] ) { method( @@ -59,18 +59,14 @@ type Query @imports( type Mutation @imports( types: [ - "Ethereum_Query", + "Ethereum_Mutation", "Ethereum_Connection", "Ethereum_TxOverrides", - "Ethereum_StaticTxResult", - "Ethereum_TxRequest", + "Ethereum_TxResponse", + "Ethereum_Access", "Ethereum_TxReceipt", "Ethereum_Log", - "Ethereum_EventNotification", - "Ethereum_Network", - "Ethereum_Mutation", - "Ethereum_TxResponse", - "Ethereum_Access" + "Ethereum_TxRequest" ] ) { method( @@ -78,6 +74,10 @@ type Mutation @imports( ): String! } +type QueryEnv { + arg1: String! +} + type Object { u: UInt! array: [Boolean!]! diff --git a/packages/cli/src/__tests__/plugin/src/.gitkeep b/packages/cli/src/__tests__/plugin/src/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/cli/src/__tests__/plugin/src/index.ts b/packages/cli/src/__tests__/plugin/src/index.ts new file mode 100644 index 0000000000..b455821d3e --- /dev/null +++ b/packages/cli/src/__tests__/plugin/src/index.ts @@ -0,0 +1,3 @@ +// TIP: All user-defined code lives in the module folders (./query, ./mutation) + +export * from "./w3"; diff --git a/packages/cli/src/__tests__/plugin/src/mutation/index.ts b/packages/cli/src/__tests__/plugin/src/mutation/index.ts new file mode 100644 index 0000000000..409a9dea15 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/src/mutation/index.ts @@ -0,0 +1,16 @@ +import { Client } from "@web3api/core-js"; +import { + Module, + Input_method +} from "./w3"; + +export interface MutationConfig extends Record { + +} + +export class Mutation extends Module { + + public method(_input: Input_method, _client: Client): string { + return "foo"; + } +} \ No newline at end of file diff --git a/packages/cli/src/__tests__/plugin/src/mutation/schema.graphql b/packages/cli/src/__tests__/plugin/src/mutation/schema.graphql new file mode 100644 index 0000000000..abe9db84a0 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/src/mutation/schema.graphql @@ -0,0 +1,7 @@ +#import { Mutation } into Ethereum from "ens/ethereum.web3api.eth" + +type Mutation { + method( + arg: UInt32! + ): String! +} diff --git a/packages/cli/src/__tests__/plugin/src/query/index.ts b/packages/cli/src/__tests__/plugin/src/query/index.ts new file mode 100644 index 0000000000..2631f7d387 --- /dev/null +++ b/packages/cli/src/__tests__/plugin/src/query/index.ts @@ -0,0 +1,21 @@ +import { Client } from "@web3api/core-js"; +import { + Module, + Object, + Input_method +} from "./w3"; + +export interface QueryConfig extends Record { + +} + +export class Query extends Module { + + public method(_input: Input_method, _client: Client): Object { + return { + u: 0, + array: [true], + bytes: null, + }; + } +} \ No newline at end of file diff --git a/packages/cli/src/__tests__/plugin/src/query/schema.graphql b/packages/cli/src/__tests__/plugin/src/query/schema.graphql new file mode 100644 index 0000000000..ef7f0933cf --- /dev/null +++ b/packages/cli/src/__tests__/plugin/src/query/schema.graphql @@ -0,0 +1,18 @@ +#import { Query } into Ethereum from "ens/ethereum.web3api.eth" + +type Query { + method( + str: String! + optStr: String + ): Object! +} + +type Object { + u: UInt! + array: [Boolean!]! + bytes: Bytes +} + +type Env { + arg1: String! +} diff --git a/packages/cli/src/__tests__/plugin/web3api.plugin.yaml b/packages/cli/src/__tests__/plugin/web3api.plugin.yaml index b21359a846..0d175848c4 100644 --- a/packages/cli/src/__tests__/plugin/web3api.plugin.yaml +++ b/packages/cli/src/__tests__/plugin/web3api.plugin.yaml @@ -1,3 +1,10 @@ -format: 0.0.1-prealpha.1 +format: 0.0.1-prealpha.2 +name: Test language: plugin/typescript -schema: ./schema.graphql +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/client-config.js b/packages/cli/src/__tests__/project/client-config.js index 1ad81a83d4..2fb12fa901 100644 --- a/packages/cli/src/__tests__/project/client-config.js +++ b/packages/cli/src/__tests__/project/client-config.js @@ -1,22 +1,29 @@ -const { Plugin } = require("@web3api/core-js"); +const { Plugin, PluginModule, PluginModules } = require("@web3api/core-js"); const mockPlugin = () => { - class MockPlugin extends Plugin { - _val = 0; - getModules(_client) { + + class Query extends PluginModule { + getData() { return this.config.val; } + } + + class Mutation extends PluginModule { + setData(input) { + this.config.val = +input.options.value; + return { txReceipt: "0xdone", value: this.config.val }; + } + + deployContract() { return "0x100"; } + } + + class MockPlugin { + _config = { + val: 0, + }; + + getModules() { return { - query: { - getData: async (_) => { - this._val; - }, - }, - mutation: { - setData: (input) => { - this._val = parseInt(input.options.value); - return { txReceipt: "0xdone", value: this._val }; - }, - deployContract: (_) => "0x100", - }, + query: new Query(this._config), + mutation: new Mutation(this._config), }; } } diff --git a/packages/cli/src/__tests__/project/client-config.ts b/packages/cli/src/__tests__/project/client-config.ts index feafdc239e..8ad9364519 100644 --- a/packages/cli/src/__tests__/project/client-config.ts +++ b/packages/cli/src/__tests__/project/client-config.ts @@ -1,25 +1,37 @@ import { Web3ApiClientConfig } from "@web3api/client-js"; -import { Plugin, Client, PluginModules } from "@web3api/core-js"; +import { Plugin, PluginModule, PluginModules } from "@web3api/core-js"; -const mockPlugin = () => { - class MockPlugin extends Plugin { - private _val: number = 0; - getModules(_client: Client): PluginModules { - return { - query: { - getData: async (_: unknown) => this._val, - }, - mutation: { - setData: (input: { options: { value: number } }) => { - this._val = +input.options.value; - return { txReceipt: "0xdone", value: this._val }; - }, - deployContract: (_) => "0x100", - }, - }; - } +interface Config extends Record { + val: number; +} + +class Query extends PluginModule { + getData(_: unknown): number { return this.config.val; } +} + +class Mutation extends PluginModule { + setData(input: { options: { value: number } }) { + this.config.val = +input.options.value; + return { txReceipt: "0xdone", value: this.config.val }; } + deployContract(): string { return "0x100"; } +} + +class MockPlugin implements Plugin { + private _config: Config = { + val: 0, + }; + + getModules(): PluginModules { + return { + query: new Query(this._config), + mutation: new Mutation(this._config), + }; + } +} + +const mockPlugin = () => { return { factory: () => new MockPlugin(), manifest: { diff --git a/packages/cli/src/__tests__/project/deploy-contracts.js b/packages/cli/src/__tests__/project/deploy-contracts.js index d0ac9fce52..dc5b78ad56 100644 --- a/packages/cli/src/__tests__/project/deploy-contracts.js +++ b/packages/cli/src/__tests__/project/deploy-contracts.js @@ -13,7 +13,7 @@ async function main() { }, }); - const address = await eth.deployContract({ + const address = await eth.getModules().mutation.deployContract({ abi: contractAbi.abi, bytecode: `0x${contractAbi.bytecode.object}`, params: [], diff --git a/packages/cli/src/__tests__/project/recipes/output.json b/packages/cli/src/__tests__/project/recipes/output.json deleted file mode 100644 index 7515d06824..0000000000 --- a/packages/cli/src/__tests__/project/recipes/output.json +++ /dev/null @@ -1 +0,0 @@ -[{"uri":"ens/testnet/simplestorage.eth","query":"mutation {\n setData(\n options: {\n address: $address\n value: $value\n }\n connection: {\n networkNameOrChainId: $network\n }\n ) {\n value\n txReceipt\n }\n}\n","variables":{"address":"0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab","value":569,"network":"testnet"},"output":{"data":{},"errors":[{}]}}] \ No newline at end of file diff --git a/packages/cli/src/__tests__/project/sample.ts b/packages/cli/src/__tests__/project/sample.ts index 69c2ec79e1..07a23276b5 100644 --- a/packages/cli/src/__tests__/project/sample.ts +++ b/packages/cli/src/__tests__/project/sample.ts @@ -558,25 +558,6 @@ 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" - ] -) { - getData( - address: String! - connection: Ethereum_Connection - ): UInt32! -} - type Mutation @imports( types: [ "Ethereum_Mutation", @@ -599,6 +580,25 @@ type Mutation @imports( ): String! } +type Query @imports( + types: [ + "Ethereum_Query", + "Ethereum_Connection", + "Ethereum_TxOverrides", + "Ethereum_StaticTxResult", + "Ethereum_TxRequest", + "Ethereum_TxReceipt", + "Ethereum_Log", + "Ethereum_EventNotification", + "Ethereum_Network" + ] +) { + getData( + address: String! + connection: Ethereum_Connection + ): UInt32! +} + type SetDataOptions { address: String! value: UInt32! @@ -611,6 +611,56 @@ type SetDataResult { ### Imported Queries START ### +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 +} + type Ethereum_Query @imported( uri: "w3://ens/ethereum.web3api.eth", namespace: "Ethereum", @@ -725,56 +775,6 @@ type Ethereum_Query @imported( ): Ethereum_Network! } -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 ### @@ -798,29 +798,39 @@ type Ethereum_TxOverrides @imported( value: BigInt } -type Ethereum_StaticTxResult @imported( +type Ethereum_TxResponse @imported( uri: "w3://ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "StaticTxResult" + nativeType: "TxResponse" ) { - result: String! - error: Boolean! + 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_TxRequest @imported( +type Ethereum_Access @imported( uri: "w3://ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "TxRequest" + nativeType: "Access" ) { - to: String - from: String - nonce: UInt32 - gasLimit: BigInt - gasPrice: BigInt - data: String - value: BigInt - chainId: BigInt - type: UInt32 + address: String! + storageKeys: [String!]! } type Ethereum_TxReceipt @imported( @@ -863,59 +873,49 @@ type Ethereum_Log @imported( logIndex: UInt32! } -type Ethereum_EventNotification @imported( +type Ethereum_TxRequest @imported( uri: "w3://ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "EventNotification" + nativeType: "TxRequest" ) { - data: String! - address: String! - log: Ethereum_Log! + to: String + from: String + nonce: UInt32 + gasLimit: BigInt + gasPrice: BigInt + data: String + value: BigInt + chainId: BigInt + type: UInt32 } -type Ethereum_Network @imported( +type Ethereum_StaticTxResult @imported( uri: "w3://ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "Network" + nativeType: "StaticTxResult" ) { - name: String! - chainId: BigInt! - ensAddress: String + result: String! + error: Boolean! } -type Ethereum_TxResponse @imported( +type Ethereum_EventNotification @imported( uri: "w3://ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "TxResponse" + nativeType: "EventNotification" ) { - 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!] + address: String! + log: Ethereum_Log! } -type Ethereum_Access @imported( +type Ethereum_Network @imported( uri: "w3://ens/ethereum.web3api.eth", namespace: "Ethereum", - nativeType: "Access" + nativeType: "Network" ) { - address: String! - storageKeys: [String!]! + name: String! + chainId: BigInt! + ensAddress: String } ### Imported Objects END ### diff --git a/packages/cli/src/lib/CodeGenerator.ts b/packages/cli/src/lib/CodeGenerator.ts index 2472a3813e..2faf764215 100644 --- a/packages/cli/src/lib/CodeGenerator.ts +++ b/packages/cli/src/lib/CodeGenerator.ts @@ -16,21 +16,16 @@ import { AnyManifest, SchemaComposer, intlMsg, + resetDir, } from "./"; -import { TypeInfo } from "@web3api/schema-parse"; -import { - bindSchema, - BindLanguage, - GenerateBindingFn, -} from "@web3api/schema-bind"; +import { BindLanguage, GenerateBindingFn } from "@web3api/schema-bind"; import { writeDirectorySync } from "@web3api/os-js"; import path from "path"; -import fs, { readFileSync } from "fs"; +import { readFileSync } from "fs"; import * as gluegun from "gluegun"; import { Ora } from "ora"; import Mustache from "mustache"; -import rimraf from "rimraf"; export interface CodeGeneratorConfig { outputDir: string; @@ -45,10 +40,10 @@ export class CodeGenerator { constructor(private _config: CodeGeneratorConfig) {} - public async generate(config?: Record): Promise { + public async generate(): Promise { try { // Compile the API - await this._generateCode(config); + await this._generateCode(); return true; } catch (e) { @@ -57,7 +52,7 @@ export class CodeGenerator { } } - private async _generateCode(config?: Record) { + private async _generateCode() { const { schemaComposer, project } = this._config; const run = async (spinner?: Ora) => { @@ -86,7 +81,7 @@ export class CodeGenerator { } // Make sure the output dir is reset - this._resetDir(this._config.outputDir); + resetDir(this._config.outputDir); // Get the fully composed schema const composed = await schemaComposer.getComposedSchemas(); @@ -124,12 +119,12 @@ export class CodeGenerator { } const output = await generateBinding({ + projectName: await project.getName(), modules: [ { name: "custom", typeInfo, schema: this._schema || "", - config: config || {}, outputDirAbs: this._config.outputDir, }, ], @@ -145,21 +140,18 @@ export class CodeGenerator { ); } } else { - const output = bindSchema({ - modules: [ - { - name: "combined", - typeInfo: composed.combined?.typeInfo as TypeInfo, - schema: composed.combined?.schema as string, - config, - outputDirAbs: this._config.outputDir, - }, - ], - bindLanguage, - }); + const output = await project.generateSchemaBindings( + composed, + this._config.outputDir + ); + // Output the bindings for (const module of output.modules) { - writeDirectorySync(this._config.outputDir, module.output); + writeDirectorySync(module.outputDirAbs, module.output); + } + + if (output.common) { + writeDirectorySync(output.common.outputDirAbs, output.common.output); } } }; @@ -178,14 +170,6 @@ export class CodeGenerator { } } - private _resetDir(dir: string) { - if (fs.existsSync(dir)) { - rimraf.sync(dir); - } - - fs.mkdirSync(dir, { recursive: true }); - } - private _generateTemplate( templatePath: string, config: unknown, diff --git a/packages/cli/src/lib/Compiler.ts b/packages/cli/src/lib/Compiler.ts index a6c2b58739..1da6d7680a 100644 --- a/packages/cli/src/lib/Compiler.ts +++ b/packages/cli/src/lib/Compiler.ts @@ -7,12 +7,12 @@ import { withSpinner, outputManifest, outputMetadata, - web3apiManifestLanguageToBindLanguage, generateDockerfile, generateDockerImageName, createBuildImage, copyArtifactsFromBuildImage, intlMsg, + resetDir, } from "./"; import { @@ -24,18 +24,11 @@ import { import { WasmWeb3Api } from "@web3api/client-js"; import { W3Imports } from "@web3api/client-js/build/wasm/types"; import { AsyncWasmInstance } from "@web3api/asyncify-js"; -import { bindSchema, BindOptions } from "@web3api/schema-bind"; -import { TypeInfo } from "@web3api/schema-parse"; import { ComposerOutput } from "@web3api/schema-compose"; -import { - getCommonPath, - writeFileSync, - writeDirectorySync, -} from "@web3api/os-js"; +import { writeFileSync, writeDirectorySync } from "@web3api/os-js"; import * as gluegun from "gluegun"; import fs from "fs"; import path from "path"; -import rimraf from "rimraf"; type ModulesToBuild = Record; @@ -99,7 +92,7 @@ export class Compiler { const state = await this._getCompilerState(); // Init & clean output directory - this._resetDir(this._config.outputDir); + resetDir(this._config.outputDir); await this._outputComposedSchema(state); @@ -196,73 +189,11 @@ export class Compiler { } private async _generateCode(state: CompilerState): Promise { - const { web3ApiManifest, composerOutput, modulesToBuild } = state; + const { composerOutput } = state; const { project } = this._config; - const queryModule = web3ApiManifest.modules.query?.module as string; - const queryDirectory = web3ApiManifest.modules.query - ? this._getGenerationDirectory(queryModule) - : undefined; - const mutationModule = web3ApiManifest.modules.mutation?.module as string; - const mutationDirectory = web3ApiManifest.modules.mutation - ? this._getGenerationDirectory(mutationModule) - : undefined; - - if ( - queryDirectory && - mutationDirectory && - queryDirectory === mutationDirectory - ) { - throw Error( - intlMsg.lib_compiler_dup_code_folder({ directory: queryDirectory }) - ); - } - - // Clean the code generation - if (queryDirectory) { - this._resetDir(queryDirectory); - } - - if (mutationDirectory) { - this._resetDir(mutationDirectory); - } - - const bindLanguage = web3apiManifestLanguageToBindLanguage( - await project.getManifestLanguage() - ); - - const options: BindOptions = { - modules: [], - bindLanguage, - }; - - if (modulesToBuild.query) { - options.modules.push({ - name: "query", - typeInfo: composerOutput.query?.typeInfo as TypeInfo, - schema: composerOutput.combined?.schema as string, - outputDirAbs: queryDirectory as string, - }); - } - - if (modulesToBuild.mutation) { - options.modules.push({ - name: "mutation", - typeInfo: composerOutput.mutation?.typeInfo as TypeInfo, - schema: composerOutput.combined?.schema as string, - outputDirAbs: mutationDirectory as string, - }); - } - - if (mutationDirectory && queryDirectory) { - options.commonDirAbs = path.join( - getCommonPath(queryDirectory, mutationDirectory), - "w3" - ); - } - // Generate the bindings - const output = bindSchema(options); + const output = await project.generateSchemaBindings(composerOutput); // Output the bindings const filesWritten: string[] = []; @@ -350,15 +281,6 @@ export class Compiler { return modulesToBuild; } - private _getGenerationDirectory(entryPoint: string): string { - const { project } = this._config; - - const absolute = path.isAbsolute(entryPoint) - ? entryPoint - : path.join(project.getManifestDir(), entryPoint); - return `${path.dirname(absolute)}/w3`; - } - private async _buildSourcesInDocker(): Promise { const { project, outputDir } = this._config; const buildManifestDir = await project.getBuildManifestDir(); @@ -417,14 +339,6 @@ export class Compiler { return dockerImageId; } - private _resetDir(dir: string) { - if (fs.existsSync(dir)) { - rimraf.sync(dir); - } - - fs.mkdirSync(dir, { recursive: true }); - } - private async _outputComposedSchema(state: CompilerState): Promise { const { outputDir } = this._config; diff --git a/packages/cli/src/lib/SchemaComposer.ts b/packages/cli/src/lib/SchemaComposer.ts index 597b6ebc84..9d572e14a9 100644 --- a/packages/cli/src/lib/SchemaComposer.ts +++ b/packages/cli/src/lib/SchemaComposer.ts @@ -9,7 +9,6 @@ import { ComposerOutput, ComposerFilter, ComposerOptions, - SchemaKind, SchemaFile, } from "@web3api/schema-compose"; import fs from "fs"; @@ -73,16 +72,7 @@ export class SchemaComposer { throw Error(`Schema "${name}" cannot be loaded at path: ${schemaPath}`); } - const isPlugin = - (await project.getManifestLanguage()).indexOf("plugin/") > -1; - - if (isPlugin) { - options.schemas.plugin = schemaFile; - } else { - // TODO: this is bad, will remove when we don't have "fixed" schema kinds, - // and just have individual modules - options.schemas[name as SchemaKind] = schemaFile; - } + options.schemas[name] = schemaFile; } this._composerOutput = await composeSchema(options); diff --git a/packages/cli/src/lib/helpers/client.ts b/packages/cli/src/lib/helpers/client.ts index a7cb60a101..854026d055 100644 --- a/packages/cli/src/lib/helpers/client.ts +++ b/packages/cli/src/lib/helpers/client.ts @@ -17,8 +17,10 @@ export function getSimpleClient(config: SimpleClientConfig): Web3ApiClient { plugins.push({ uri: "w3://ens/ens.web3api.eth", plugin: ensPlugin({ - addresses: { - testnet: ensAddress, + query: { + addresses: { + testnet: ensAddress, + }, }, }), }); diff --git a/packages/cli/src/lib/project/AppProject.ts b/packages/cli/src/lib/project/AppProject.ts index e11e55d203..e7f8223760 100644 --- a/packages/cli/src/lib/project/AppProject.ts +++ b/packages/cli/src/lib/project/AppProject.ts @@ -4,9 +4,13 @@ import { appManifestLanguages, isAppManifestLanguage, loadAppManifest, + appManifestLanguageToBindLanguage, } from ".."; import { AppManifest, Client } from "@web3api/core-js"; +import { ComposerOutput } from "@web3api/schema-compose"; +import { bindSchema, BindOutput } from "@web3api/schema-bind"; +import { TypeInfo } from "@web3api/schema-parse"; import path from "path"; const cacheLayout = { @@ -45,6 +49,10 @@ export class AppProject extends Project { /// Manifest (web3api.app.yaml) + public async getName(): Promise { + return (await this.getManifest()).name; + } + public async getManifest(): Promise { if (!this._appManifest) { this._appManifest = await loadAppManifest( @@ -76,7 +84,7 @@ export class AppProject extends Project { return language as AppManifestLanguage; } - /// ProjectWithSchema Base Methods + /// Schema public async getSchemaNamedPaths(): Promise<{ [name: string]: string; @@ -98,4 +106,24 @@ export class AppProject extends Project { const manifest = await this.getManifest(); return manifest.import_redirects || []; } + + public async generateSchemaBindings( + composerOutput: ComposerOutput, + outputDir?: string + ): Promise { + return bindSchema({ + projectName: await this.getName(), + modules: [ + { + name: "combined", + typeInfo: composerOutput.combined?.typeInfo as TypeInfo, + schema: composerOutput.combined?.schema as string, + outputDirAbs: outputDir || path.join(this.getManifestDir(), "src/w3"), + }, + ], + bindLanguage: appManifestLanguageToBindLanguage( + await this.getManifestLanguage() + ), + }); + } } diff --git a/packages/cli/src/lib/project/PluginProject.ts b/packages/cli/src/lib/project/PluginProject.ts index 997cfd6c51..c4cb27d292 100644 --- a/packages/cli/src/lib/project/PluginProject.ts +++ b/packages/cli/src/lib/project/PluginProject.ts @@ -4,9 +4,16 @@ import { PluginManifestLanguage, pluginManifestLanguages, isPluginManifestLanguage, + pluginManifestLanguageToBindLanguage, + intlMsg, + resetDir, } from ".."; import { PluginManifest } from "@web3api/core-js"; +import { getCommonPath } from "@web3api/os-js"; +import { bindSchema, BindOutput, BindOptions } from "@web3api/schema-bind"; +import { ComposerOutput } from "@web3api/schema-compose"; +import { TypeInfo } from "@web3api/schema-parse"; import path from "path"; const cacheLayout = { @@ -44,6 +51,10 @@ export class PluginProject extends Project { /// Manifest (web3api.plugin.yaml) + public async getName(): Promise { + return (await this.getManifest()).name; + } + public async getManifest(): Promise { if (!this._pluginManifest) { this._pluginManifest = await loadPluginManifest( @@ -75,7 +86,7 @@ export class PluginProject extends Project { return language as PluginManifestLanguage; } - /// ProjectWithSchema Base Methods + /// Schema public async getSchemaNamedPaths(): Promise<{ [name: string]: string; @@ -84,7 +95,14 @@ export class PluginProject extends Project { const dir = this.getManifestDir(); const namedPaths: { [name: string]: string } = {}; - namedPaths["combined"] = path.join(dir, manifest.schema); + if (manifest.modules.mutation) { + namedPaths["mutation"] = path.join(dir, manifest.modules.mutation.schema); + } + + if (manifest.modules.query) { + namedPaths["query"] = path.join(dir, manifest.modules.query.schema); + } + return namedPaths; } @@ -97,4 +115,85 @@ export class PluginProject extends Project { const manifest = await this.getManifest(); return manifest.import_redirects || []; } + + public async generateSchemaBindings( + composerOutput: ComposerOutput + ): Promise { + const manifest = await this.getManifest(); + const queryModule = manifest.modules.query?.module as string; + const queryDirectory = manifest.modules.query + ? this._getGenerationDirectory(queryModule) + : undefined; + const mutationModule = manifest.modules.mutation?.module as string; + const mutationDirectory = manifest.modules.mutation + ? this._getGenerationDirectory(mutationModule) + : undefined; + + if ( + queryDirectory && + mutationDirectory && + queryDirectory === mutationDirectory + ) { + throw Error( + intlMsg.lib_compiler_dup_code_folder({ directory: queryDirectory }) + ); + } + + // Clean the code generation + if (queryDirectory) { + resetDir(queryDirectory); + } + + if (mutationDirectory) { + resetDir(mutationDirectory); + } + + const bindLanguage = pluginManifestLanguageToBindLanguage( + await this.getManifestLanguage() + ); + + const options: BindOptions = { + projectName: manifest.name, + modules: [], + bindLanguage, + }; + + if (manifest.modules.query) { + options.modules.push({ + name: "query", + typeInfo: composerOutput.query?.typeInfo as TypeInfo, + schema: composerOutput.combined?.schema as string, + outputDirAbs: queryDirectory as string, + }); + } + + if (manifest.modules.mutation) { + options.modules.push({ + name: "mutation", + typeInfo: composerOutput.mutation?.typeInfo as TypeInfo, + schema: composerOutput.combined?.schema as string, + outputDirAbs: mutationDirectory as string, + }); + } + + if (mutationDirectory && queryDirectory) { + options.commonDirAbs = path.join( + getCommonPath(queryDirectory, mutationDirectory), + "w3" + ); + } else if (mutationDirectory || queryDirectory) { + options.commonDirAbs = path.resolve( + path.join(mutationDirectory || queryDirectory || "", "../w3") + ); + } + + return bindSchema(options); + } + + private _getGenerationDirectory(entryPoint: string): string { + const absolute = path.isAbsolute(entryPoint) + ? entryPoint + : path.join(this.getManifestDir(), entryPoint); + return `${path.dirname(absolute)}/w3`; + } } diff --git a/packages/cli/src/lib/project/Project.ts b/packages/cli/src/lib/project/Project.ts index 63b4296ddc..cb37f8e429 100644 --- a/packages/cli/src/lib/project/Project.ts +++ b/packages/cli/src/lib/project/Project.ts @@ -5,6 +5,8 @@ import path from "path"; import rimraf from "rimraf"; import copyfiles from "copyfiles"; import { writeFileSync } from "@web3api/os-js"; +import { BindOutput } from "@web3api/schema-bind"; +import { ComposerOutput } from "@web3api/schema-compose"; export interface ProjectConfig { rootCacheDir: string; @@ -44,6 +46,8 @@ export abstract class Project { public abstract validate(): Promise; + public abstract getName(): Promise; + public abstract getManifest(): Promise; public abstract getManifestDir(): string; @@ -63,6 +67,11 @@ export abstract class Project { }[] >; + public abstract generateSchemaBindings( + composerOutput: ComposerOutput, + outputDir?: string + ): Promise; + public get quiet(): boolean { return !!this._config.quiet; } diff --git a/packages/cli/src/lib/project/Web3ApiProject.ts b/packages/cli/src/lib/project/Web3ApiProject.ts index 4664c7cdc3..769652b59f 100644 --- a/packages/cli/src/lib/project/Web3ApiProject.ts +++ b/packages/cli/src/lib/project/Web3ApiProject.ts @@ -12,10 +12,15 @@ import { isWeb3ApiManifestLanguage, outputManifest, intlMsg, + web3apiManifestLanguageToBindLanguage, + resetDir, } from ".."; import { Web3ApiManifest, BuildManifest, MetaManifest } from "@web3api/core-js"; import { getCommonPath, normalizePath } from "@web3api/os-js"; +import { bindSchema, BindOutput, BindOptions } from "@web3api/schema-bind"; +import { ComposerOutput } from "@web3api/schema-compose"; +import { TypeInfo } from "@web3api/schema-parse"; import regexParser from "regex-parser"; import path from "path"; import fs from "fs"; @@ -52,7 +57,8 @@ export class Web3ApiProject extends Project { this._buildManifest = undefined; this._metaManifest = undefined; this._defaultBuildManifestCached = false; - this.resetCache(); + this.removeCacheDir(cacheLayout.buildEnvDir); + this.removeCacheDir(cacheLayout.buildLinkedPackagesDir); } public async validate(): Promise { @@ -61,6 +67,10 @@ export class Web3ApiProject extends Project { /// Manifest (web3api.yaml) + public async getName(): Promise { + return (await this.getManifest()).name; + } + public async getManifest(): Promise { if (!this._web3apiManifest) { this._web3apiManifest = await loadWeb3ApiManifest( @@ -92,7 +102,7 @@ export class Web3ApiProject extends Project { return language as Web3ApiManifestLanguage; } - /// ProjectWithSchema Base Methods + /// Schema public async getSchemaNamedPaths(): Promise<{ [name: string]: string; @@ -122,6 +132,76 @@ export class Web3ApiProject extends Project { return manifest.import_redirects || []; } + public async generateSchemaBindings( + composerOutput: ComposerOutput + ): Promise { + const manifest = await this.getManifest(); + const queryModule = manifest.modules.query?.module as string; + const queryDirectory = manifest.modules.query + ? this._getGenerationDirectory(queryModule) + : undefined; + const mutationModule = manifest.modules.mutation?.module as string; + const mutationDirectory = manifest.modules.mutation + ? this._getGenerationDirectory(mutationModule) + : undefined; + + if ( + queryDirectory && + mutationDirectory && + queryDirectory === mutationDirectory + ) { + throw Error( + intlMsg.lib_compiler_dup_code_folder({ directory: queryDirectory }) + ); + } + + // Clean the code generation + if (queryDirectory) { + resetDir(queryDirectory); + } + + if (mutationDirectory) { + resetDir(mutationDirectory); + } + + const bindLanguage = web3apiManifestLanguageToBindLanguage( + await this.getManifestLanguage() + ); + + const options: BindOptions = { + projectName: manifest.name, + modules: [], + bindLanguage, + }; + + if (manifest.modules.query) { + options.modules.push({ + name: "query", + typeInfo: composerOutput.query?.typeInfo as TypeInfo, + schema: composerOutput.combined?.schema as string, + outputDirAbs: queryDirectory as string, + }); + } + + if (manifest.modules.mutation) { + options.modules.push({ + name: "mutation", + typeInfo: composerOutput.mutation?.typeInfo as TypeInfo, + schema: composerOutput.combined?.schema as string, + outputDirAbs: mutationDirectory as string, + }); + } + + if (mutationDirectory && queryDirectory) { + options.commonDirAbs = path.join( + getCommonPath(queryDirectory, mutationDirectory), + "w3" + ); + } + + return bindSchema(options); + } + /// Web3API Build Manifest (web3api.build.yaml) public async getBuildManifestPath(): Promise { @@ -422,4 +502,11 @@ export class Web3ApiProject extends Project { commonDir, }; } + + private _getGenerationDirectory(entryPoint: string): string { + const absolute = path.isAbsolute(entryPoint) + ? entryPoint + : path.join(this.getManifestDir(), entryPoint); + return `${path.dirname(absolute)}/w3`; + } } diff --git a/packages/cli/src/lib/system/filesystem.ts b/packages/cli/src/lib/system/filesystem.ts new file mode 100644 index 0000000000..d8a7602e73 --- /dev/null +++ b/packages/cli/src/lib/system/filesystem.ts @@ -0,0 +1,10 @@ +import fs from "fs"; +import rimraf from "rimraf"; + +export function resetDir(dir: string): void { + if (fs.existsSync(dir)) { + rimraf.sync(dir); + } + + fs.mkdirSync(dir, { recursive: true }); +} diff --git a/packages/cli/src/lib/system/index.ts b/packages/cli/src/lib/system/index.ts index 2610c8eb07..b92455ee94 100644 --- a/packages/cli/src/lib/system/index.ts +++ b/packages/cli/src/lib/system/index.ts @@ -2,5 +2,6 @@ export * from "./child-process"; export * from "./docker"; export * from "./file-lock"; export * from "./file-watcher"; +export * from "./filesystem"; export * from "./path"; export * from "./typescript"; diff --git a/packages/cli/src/lib/test-env/client-config.ts b/packages/cli/src/lib/test-env/client-config.ts index cd2b8d953d..38cd69f880 100644 --- a/packages/cli/src/lib/test-env/client-config.ts +++ b/packages/cli/src/lib/test-env/client-config.ts @@ -52,8 +52,10 @@ export async function getTestEnvClientConfig(): Promise< { uri: "w3://ens/ens.web3api.eth", plugin: ensPlugin({ - addresses: { - testnet: ensAddress, + query: { + addresses: { + testnet: ensAddress, + }, }, }), }, diff --git a/packages/js/client/scripts/extractPluginConfigs.ts b/packages/js/client/scripts/extractPluginConfigs.ts index 8d6098f8f5..ed2d7c8756 100644 --- a/packages/js/client/scripts/extractPluginConfigs.ts +++ b/packages/js/client/scripts/extractPluginConfigs.ts @@ -23,24 +23,34 @@ const plugins: PluginConfigSource[] = [ name: "Ipfs", module: "@web3api/ipfs-plugin-js", uri: "w3://ens/ipfs.web3api.eth", - config: "IpfsConfig", - files: [{ - name: "build/index.d.ts", - interfaces: ["IpfsConfig"] - }] + config: "IpfsPluginConfigs", + files: [ + { + name: "build/index.d.ts", + interfaces: ["IpfsPluginConfigs"] + }, + { + name: "build/common/IpfsConfig.d.ts", + interfaces: ["IpfsConfig"], + } + ], }, { name: "Ethereum", module: "@web3api/ethereum-plugin-js", uri: "w3://ens/ethereum.web3api.eth", - config: "EthereumConfig", + config: "EthereumPluginConfigs", files: [ { name: "build/index.d.ts", + interfaces: ["EthereumPluginConfigs"], + }, + { + name: "build/common/EthereumConfig.d.ts", interfaces: ["EthereumConfig"], }, { - name: "build/Connection.d.ts", + name: "build/common/Connection.d.ts", interfaces: ["ConnectionConfig", "ConnectionConfigs"], types: ["EthereumProvider", "EthereumSigner", "AccountIndex", "Address"], }, @@ -64,12 +74,18 @@ const plugins: PluginConfigSource[] = [ name: "Ens", module: "@web3api/ens-plugin-js", uri: "w3://ens/ens.web3api.eth", - config: "EnsConfig", - files: [{ - name: "build/index.d.ts", - interfaces: ["EnsConfig", "Addresses"], - types: ["Address"] - }] + config: "EnsPluginConfigs", + files: [ + { + name: "build/w3-man/plugin.d.ts", + interfaces: ["EnsPluginConfigs"], + }, + { + name: "build/query/index.d.ts", + interfaces: ["QueryConfig", "Addresses"], + types: ["Address"], + }, + ] } ]; diff --git a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts index d4c5a81cdb..1b7eef662d 100644 --- a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts +++ b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts @@ -19,7 +19,7 @@ import { deserializeBuildManifest, deserializeMetaManifest, coreInterfaceUris, - Client, + PluginModule, PluginModules, msgpackDecode, } from "@web3api/core-js"; @@ -55,8 +55,10 @@ describe("Web3ApiClient", () => { }, ipfs: { provider: ipfsProvider }, ens: { - addresses: { - testnet: ensAddress, + query: { + addresses: { + testnet: ensAddress, + }, }, }, }, @@ -65,15 +67,19 @@ describe("Web3ApiClient", () => { }; const mockPlugin = () => { - class MockPlugin extends Plugin { - getModules(_client: Client): PluginModules { + class Query extends PluginModule { + getData(_: unknown) { return 100; } + } + + class Mutation extends PluginModule { + deployContract(_: unknown): string { return "0x100" } + } + + class MockPlugin implements Plugin { + getModules(): PluginModules { return { - query: { - getData: async (_: unknown) => 100, - }, - mutation: { - deployContract: (_: unknown): string => "0x100", - }, + query: new Query({}), + mutation: new Mutation({}), }; } } @@ -88,27 +94,36 @@ describe("Web3ApiClient", () => { }; const mockMapPlugin = () => { - class MockMapPlugin extends Plugin { - private map: Map = new Map().set("a", 1).set("b", 2); + interface Config extends Record { + map: Map; + } + + class Query extends PluginModule { + async getMap(_: unknown) { return this.config.map } + } - getModules(_client: Client): PluginModules { + class Mutation extends PluginModule { + updateMap(input: { + map: Map; + }): Map { + for (const key of input.map.keys()) { + this.config.map.set( + key, + (this.config.map.get(key) || 0) + (input.map.get(key) || 0) + ); + } + return this.config.map; + } + } + + class MockMapPlugin implements Plugin { + + private map = new Map().set("a", 1).set("b", 2) + + getModules(): PluginModules { return { - query: { - getMap: async (_: unknown) => this.map, - }, - mutation: { - updateMap: (input: { - map: Map; - }): Map => { - for (const key of input.map.keys()) { - this.map.set( - key, - (this.map.get(key) || 0) + (input.map.get(key) || 0) - ); - } - return this.map; - }, - }, + query: new Query({ map: this.map }), + mutation: new Mutation({ map: this.map }), }; } } diff --git a/packages/js/client/src/__tests__/env.spec.ts b/packages/js/client/src/__tests__/env.spec.ts index 8cb5170d6b..067185dd66 100644 --- a/packages/js/client/src/__tests__/env.spec.ts +++ b/packages/js/client/src/__tests__/env.spec.ts @@ -4,7 +4,7 @@ import { stopTestEnvironment, } from "@web3api/test-env-js"; import { createWeb3ApiClient, Web3ApiClientConfig } from ".."; -import { Client, Plugin, PluginModules } from "@web3api/core-js"; +import { Client, Plugin, PluginModule, PluginModules } from "@web3api/core-js"; import { GetPathToTestApis } from "@web3api/test-cases"; jest.setTimeout(200000); @@ -37,8 +37,10 @@ describe("env", () => { }, ipfs: { provider: ipfsProvider }, ens: { - addresses: { - testnet: ensAddress, + query: { + addresses: { + testnet: ensAddress, + }, }, }, }, @@ -47,28 +49,43 @@ describe("env", () => { }; const mockEnvPlugin = () => { - class MockEnvPlugin extends Plugin { - getModules(_client: Client): PluginModules { + interface Env extends Record { + arg1: number; + } + + interface ClientEnv extends Record { + arg1: string; + } + + class Query extends PluginModule<{}, Env, ClientEnv> { + sanitizeEnv(env: ClientEnv): Env { + return { arg1: parseInt(env.arg1) }; + } + + queryEnv(): Env { + return this.env; + } + } + + class Mutation extends PluginModule<{}, ClientEnv, Env> { + sanitizeEnv(env: Env): ClientEnv { + return { arg1: env.arg1.toString() }; + } + + mutationEnv(): ClientEnv { + return this.env; + } + } + + class MockEnvPlugin implements Plugin { + getModules(): PluginModules { return { - query: { - sanitizeEnv: async (env: { arg1: string }) => { - return { arg1: parseInt(env.arg1) }; - }, - queryEnv: () => { - return this.getEnv("query"); - }, - }, - mutation: { - sanitizeEnv: async (env: { arg1: number }) => { - return { arg1: env.arg1.toString() }; - }, - mutationEnv: () => { - return this.getEnv("mutation"); - }, - }, + query: new Query({}), + mutation: new Mutation({}), }; } } + return { factory: () => new MockEnvPlugin(), manifest: { diff --git a/packages/js/client/src/__tests__/resolveUri.spec.ts b/packages/js/client/src/__tests__/resolveUri.spec.ts index 10a87f739a..f2499f2b9d 100644 --- a/packages/js/client/src/__tests__/resolveUri.spec.ts +++ b/packages/js/client/src/__tests__/resolveUri.spec.ts @@ -44,8 +44,10 @@ describe("Web3ApiClient - resolveUri", () => { }, ipfs: { provider: ipfsProvider }, ens: { - addresses: { - testnet: ensAddress, + query: { + addresses: { + testnet: ensAddress, + }, }, }, }, diff --git a/packages/js/client/src/default-client-config.ts b/packages/js/client/src/default-client-config.ts index 7d25255486..1ea7c18234 100644 --- a/packages/js/client/src/default-client-config.ts +++ b/packages/js/client/src/default-client-config.ts @@ -41,7 +41,7 @@ export const getDefaultClientConfig = Tracer.traceFunc( // ENS is required for resolving domain to IPFS hashes { uri: new Uri("w3://ens/ens.web3api.eth"), - plugin: ensPlugin({}), + plugin: ensPlugin({ query: {} }), }, { uri: new Uri("w3://ens/ethereum.web3api.eth"), @@ -56,29 +56,31 @@ export const getDefaultClientConfig = Tracer.traceFunc( }, { uri: new Uri("w3://ens/http.web3api.eth"), - plugin: httpPlugin(), + plugin: httpPlugin({ query: {} }), }, { uri: new Uri("w3://ens/js-logger.web3api.eth"), - plugin: loggerPlugin(), + plugin: loggerPlugin({ query: {} }), }, { uri: new Uri("w3://ens/uts46.web3api.eth"), - plugin: uts46Plugin(), + plugin: uts46Plugin({ query: {} }), }, { uri: new Uri("w3://ens/sha3.web3api.eth"), - plugin: sha3Plugin(), + plugin: sha3Plugin({ query: {} }), }, { uri: new Uri("w3://ens/graph-node.web3api.eth"), plugin: graphNodePlugin({ - provider: "https://api.thegraph.com", + query: { + provider: "https://api.thegraph.com", + }, }), }, { uri: new Uri("w3://ens/fs.web3api.eth"), - plugin: filesystemPlugin(), + plugin: filesystemPlugin({ query: {} }), }, ], interfaces: [ diff --git a/packages/js/client/src/plugin/PluginWeb3Api.ts b/packages/js/client/src/plugin/PluginWeb3Api.ts index c744b90de9..648f1f8614 100644 --- a/packages/js/client/src/plugin/PluginWeb3Api.ts +++ b/packages/js/client/src/plugin/PluginWeb3Api.ts @@ -1,12 +1,12 @@ import { Api, Client, - executeMaybeAsyncFunction, filterResults, GetManifestOptions, InvokeApiOptions, InvokeApiResult, Plugin, + PluginModule, PluginPackage, Uri, AnyManifestArtifact, @@ -19,13 +19,17 @@ import { } from "@web3api/core-js"; import { Tracer } from "@web3api/tracing-js"; -function isValidEnv(env: Record): boolean { - return typeof env === "object" && !Array.isArray(env) && env !== null; -} - export class PluginWeb3Api extends Api { private _instance: Plugin | undefined; + private _sanitizedEnv: Record< + InvokableModules, + Record | undefined + > = { + query: undefined, + mutation: undefined, + }; + constructor( private _uri: Uri, private _plugin: PluginPackage, @@ -68,29 +72,19 @@ export class PluginWeb3Api extends Api { try { const { module, method, resultFilter } = options; const input = options.input || {}; - const modules = this._getInstance().getModules(client); + const modules = this._getInstance().getModules(); const pluginModule = modules[module]; if (!pluginModule) { throw new Error(`PluginWeb3Api: module "${module}" not found.`); } - if (!pluginModule[method]) { + if (!pluginModule.getMethod(method)) { throw new Error(`PluginWeb3Api: method "${method}" not found.`); } - let env = this._getModuleClientEnv(module); - if (isValidEnv(env)) { - if (pluginModule["sanitizeEnv"]) { - env = (await executeMaybeAsyncFunction( - pluginModule["sanitizeEnv"], - env, - client - )) as Record; - } - - this._getInstance().loadEnv(env, module); - } + // Sanitize & load the module's environment + await this._sanitizeAndLoadEnv(client, module, pluginModule); let jsInput: Record; @@ -111,9 +105,10 @@ export class PluginWeb3Api extends Api { jsInput = input; } + // Invoke the function try { - const result = (await executeMaybeAsyncFunction( - pluginModule[method], + const result = (await pluginModule._w3_invoke( + method, jsInput, client )) as TData; @@ -174,7 +169,24 @@ export class PluginWeb3Api extends Api { return this._instance; } - @Tracer.traceMethod("PluginWeb3Api: getModuleClientEnv") + @Tracer.traceMethod("PluginWeb3Api: _sanitizeAndLoadEnv") + private async _sanitizeAndLoadEnv( + client: Client, + module: InvokableModules, + pluginModule: PluginModule + ): Promise { + if (this._sanitizedEnv[module] === undefined) { + const clientEnv = this._getModuleClientEnv(module); + + const env = await pluginModule._w3_sanitize_env(clientEnv, client); + + this._sanitizedEnv[module] = env; + } + + pluginModule._w3_load_env(this._sanitizedEnv[module] || {}); + } + + @Tracer.traceMethod("PluginWeb3Api: _getModuleClientEnv") private _getModuleClientEnv( module: InvokableModules ): Record { diff --git a/packages/js/client/src/pluginConfigs/Ens.ts b/packages/js/client/src/pluginConfigs/Ens.ts index c9c063709c..d2cd5c6690 100644 --- a/packages/js/client/src/pluginConfigs/Ens.ts +++ b/packages/js/client/src/pluginConfigs/Ens.ts @@ -2,9 +2,13 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /// Types generated from @web3api/ens-plugin-js build files: -/// build/index.d.ts +/// build/w3-man/plugin.d.ts, build/query/index.d.ts -export interface EnsConfig { +export interface EnsPluginConfigs { + query: QueryConfig; +} + +export interface QueryConfig extends Record { addresses?: Addresses; } diff --git a/packages/js/client/src/pluginConfigs/Ethereum.ts b/packages/js/client/src/pluginConfigs/Ethereum.ts index 553a24875a..6a828e3d18 100644 --- a/packages/js/client/src/pluginConfigs/Ethereum.ts +++ b/packages/js/client/src/pluginConfigs/Ethereum.ts @@ -2,7 +2,11 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /// Types generated from @web3api/ethereum-plugin-js build files: -/// build/index.d.ts, build/Connection.d.ts +/// build/index.d.ts, build/common/EthereumConfig.d.ts, build/common/Connection.d.ts + +export interface EthereumPluginConfigs + extends EthereumConfig, + Record {} export interface EthereumConfig { networks: ConnectionConfigs; diff --git a/packages/js/client/src/pluginConfigs/Ipfs.ts b/packages/js/client/src/pluginConfigs/Ipfs.ts index 4b0acba33a..6a50482364 100644 --- a/packages/js/client/src/pluginConfigs/Ipfs.ts +++ b/packages/js/client/src/pluginConfigs/Ipfs.ts @@ -2,7 +2,11 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /// Types generated from @web3api/ipfs-plugin-js build files: -/// build/index.d.ts +/// build/index.d.ts, build/common/IpfsConfig.d.ts + +export interface IpfsPluginConfigs + extends IpfsConfig, + Record {} export interface IpfsConfig { provider: string; diff --git a/packages/js/client/src/pluginConfigs/index.ts b/packages/js/client/src/pluginConfigs/index.ts index ee3afa1422..0a89c427e0 100644 --- a/packages/js/client/src/pluginConfigs/index.ts +++ b/packages/js/client/src/pluginConfigs/index.ts @@ -1,14 +1,14 @@ /// NOTE: This is an auto-generated file. See scripts/extractPluginConfigs.ts /* eslint-disable @typescript-eslint/no-explicit-any */ -import { IpfsConfig } from "./Ipfs"; -import { EthereumConfig } from "./Ethereum"; -import { EnsConfig } from "./Ens"; +import { IpfsPluginConfigs } from "./Ipfs"; +import { EthereumPluginConfigs } from "./Ethereum"; +import { EnsPluginConfigs } from "./Ens"; interface PluginConfigs { - ipfs?: IpfsConfig; - ethereum?: EthereumConfig; - ens?: EnsConfig; + ipfs?: IpfsPluginConfigs; + ethereum?: EthereumPluginConfigs; + ens?: EnsPluginConfigs; } const modules: Record = { diff --git a/packages/js/core/src/__tests__/Plugin.spec.ts b/packages/js/core/src/__tests__/Plugin.spec.ts index ade56938bf..3182399347 100644 --- a/packages/js/core/src/__tests__/Plugin.spec.ts +++ b/packages/js/core/src/__tests__/Plugin.spec.ts @@ -2,6 +2,7 @@ import { Client, Plugin, PluginModules, + PluginModule, PluginPackageManifest, Uri, } from ".."; @@ -19,19 +20,23 @@ const testPluginManifest: PluginPackageManifest = { implements: [new Uri("host2/path2")], }; -class TestPlugin extends Plugin { - public getModules(_client: Client): PluginModules { +class TestPluginQuery extends PluginModule { + testQuery(_input: unknown, _client: Client): number { + return 5; + } +} + +class TestPluginMutation extends PluginModule { + testMutation(_input: unknown, _client: Client): Promise { + return Promise.resolve(true); + } +} + +class TestPlugin implements Plugin { + public getModules(): PluginModules { return { - query: { - testQuery: (_input: unknown, _client: Client): number => { - return 5; - }, - }, - mutation: { - testMutation: (_input: unknown, _client: Client): Promise => { - return Promise.resolve(true); - }, - }, + query: new TestPluginQuery({}), + mutation: new TestPluginMutation({}), }; } } @@ -40,10 +45,10 @@ describe("Plugin", () => { const plugin = new TestPlugin(); it("sanity", () => { - const modules = plugin.getModules({} as Client); + const modules = plugin.getModules(); expect(testPluginManifest.implements.length).toBe(1); expect(modules.mutation).toBeTruthy(); - expect(modules.mutation?.testMutation).toBeTruthy(); + expect(modules.mutation?.getMethod("testMutation")).toBeTruthy(); }); }); diff --git a/packages/js/core/src/manifest/formats/web3api.plugin/0.0.1-prealpha.3.ts b/packages/js/core/src/manifest/formats/web3api.app/0.0.1-prealpha.2.ts similarity index 79% rename from packages/js/core/src/manifest/formats/web3api.plugin/0.0.1-prealpha.3.ts rename to packages/js/core/src/manifest/formats/web3api.app/0.0.1-prealpha.2.ts index f8b85a66e8..159036fb58 100644 --- a/packages/js/core/src/manifest/formats/web3api.plugin/0.0.1-prealpha.3.ts +++ b/packages/js/core/src/manifest/formats/web3api.app/0.0.1-prealpha.2.ts @@ -6,13 +6,14 @@ * and run json-schema-to-typescript to regenerate this file. */ -export interface PluginManifest { - format: "0.0.1-prealpha.3"; +export interface AppManifest { + format: "0.0.1-prealpha.2"; + name: string; language: string; schema: string; import_redirects?: { uri: string; schema: string; }[]; - __type: "PluginManifest"; + __type: "AppManifest"; } diff --git a/packages/js/core/src/manifest/formats/web3api.app/index.ts b/packages/js/core/src/manifest/formats/web3api.app/index.ts index d949f57062..588ffb7ca7 100644 --- a/packages/js/core/src/manifest/formats/web3api.app/index.ts +++ b/packages/js/core/src/manifest/formats/web3api.app/index.ts @@ -8,21 +8,27 @@ import { AppManifest as AppManifest0_0_1_prealpha_1 } from "./0.0.1-prealpha.1"; +import { + AppManifest as AppManifest0_0_1_prealpha_2 +} from "./0.0.1-prealpha.2"; export { AppManifest0_0_1_prealpha_1, + AppManifest0_0_1_prealpha_2, }; export enum AppManifestFormats { "0.0.1-prealpha.1" = "0.0.1-prealpha.1", + "0.0.1-prealpha.2" = "0.0.1-prealpha.2", } export type AnyAppManifest = | AppManifest0_0_1_prealpha_1 + | AppManifest0_0_1_prealpha_2 -export type AppManifest = AppManifest0_0_1_prealpha_1; +export type AppManifest = AppManifest0_0_1_prealpha_2; -export const latestAppManifestFormat = AppManifestFormats["0.0.1-prealpha.1"] +export const latestAppManifestFormat = AppManifestFormats["0.0.1-prealpha.2"] export { migrateAppManifest } from "./migrate"; diff --git a/packages/js/core/src/manifest/formats/web3api.app/migrate.ts b/packages/js/core/src/manifest/formats/web3api.app/migrate.ts index 32c18b6480..a7c9782528 100644 --- a/packages/js/core/src/manifest/formats/web3api.app/migrate.ts +++ b/packages/js/core/src/manifest/formats/web3api.app/migrate.ts @@ -11,6 +11,9 @@ import { latestAppManifestFormat } from "."; +import { + migrate as migrate_0_0_1_prealpha_1_to_0_0_1_prealpha_2 +} from "./migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.2"; import { Tracer } from "@web3api/tracing-js"; @@ -19,6 +22,7 @@ type Migrator = { }; export const migrators: Migrator = { + "0.0.1-prealpha.1": migrate_0_0_1_prealpha_1_to_0_0_1_prealpha_2, }; export const migrateAppManifest = Tracer.traceFunc( @@ -34,6 +38,13 @@ export const migrateAppManifest = Tracer.traceFunc( throw new Error(`Unrecognized AppManifestFormat "${manifest.format}"`); } - throw new Error(`This should never happen, AppManifest migrators is empty. from: ${from}, to: ${to}`); + const migrator = migrators[from]; + if (!migrator) { + throw new Error( + `Migrator from AppManifestFormat "${from}" to "${to}" is not available` + ); + } + + return migrator(manifest); } ); diff --git a/packages/js/core/src/manifest/formats/web3api.app/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.2.ts b/packages/js/core/src/manifest/formats/web3api.app/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.2.ts new file mode 100644 index 0000000000..adeb6ff8f3 --- /dev/null +++ b/packages/js/core/src/manifest/formats/web3api.app/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.2.ts @@ -0,0 +1,13 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + +import { AppManifest as OldManifest } from "../0.0.1-prealpha.1"; +import { AppManifest as NewManifest } from "../0.0.1-prealpha.2"; + +export function migrate(old: OldManifest): NewManifest { + return { + ...old, + __type: "AppManifest", + format: "0.0.1-prealpha.2", + name: "Unnamed", + }; +} diff --git a/packages/js/core/src/manifest/formats/web3api.app/validate.ts b/packages/js/core/src/manifest/formats/web3api.app/validate.ts index a00710f2da..cef2669bce 100644 --- a/packages/js/core/src/manifest/formats/web3api.app/validate.ts +++ b/packages/js/core/src/manifest/formats/web3api.app/validate.ts @@ -11,6 +11,7 @@ import { import * as Validators from "../../validators"; import schema_0_0_1_prealpha_1 from "@web3api/manifest-schemas/formats/web3api.app/0.0.1-prealpha.1.json"; +import schema_0_0_1_prealpha_2 from "@web3api/manifest-schemas/formats/web3api.app/0.0.1-prealpha.2.json"; import { Tracer } from "@web3api/tracing-js" import { @@ -26,6 +27,7 @@ type AppManifestSchemas = { const schemas: AppManifestSchemas = { "0.0.1-prealpha.1": schema_0_0_1_prealpha_1, + "0.0.1-prealpha.2": schema_0_0_1_prealpha_2, }; const validator = new Validator(); @@ -34,6 +36,7 @@ Validator.prototype.customFormats.appLanguage = Validators.appLanguage; Validator.prototype.customFormats.file = Validators.file; Validator.prototype.customFormats.web3apiUri = Validators.web3apiUri; Validator.prototype.customFormats.schemaFile = Validators.schemaFile; +Validator.prototype.customFormats.packageName = Validators.packageName; export const validateAppManifest = Tracer.traceFunc( "core: validateAppManifest", diff --git a/packages/js/core/src/manifest/formats/web3api.plugin/0.0.1-prealpha.2.ts b/packages/js/core/src/manifest/formats/web3api.plugin/0.0.1-prealpha.2.ts new file mode 100644 index 0000000000..74f3b4b64e --- /dev/null +++ b/packages/js/core/src/manifest/formats/web3api.plugin/0.0.1-prealpha.2.ts @@ -0,0 +1,28 @@ +/* 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 PluginManifest { + format: "0.0.1-prealpha.2"; + name: string; + language: string; + modules: { + mutation?: { + schema: string; + module?: string; + }; + query?: { + schema: string; + module?: string; + }; + }; + import_redirects?: { + uri: string; + schema: string; + }[]; + __type: "PluginManifest"; +} diff --git a/packages/js/core/src/manifest/formats/web3api.plugin/index.ts b/packages/js/core/src/manifest/formats/web3api.plugin/index.ts index 89bc4c0fbf..50ab739644 100644 --- a/packages/js/core/src/manifest/formats/web3api.plugin/index.ts +++ b/packages/js/core/src/manifest/formats/web3api.plugin/index.ts @@ -8,21 +8,27 @@ import { PluginManifest as PluginManifest0_0_1_prealpha_1 } from "./0.0.1-prealpha.1"; +import { + PluginManifest as PluginManifest0_0_1_prealpha_2 +} from "./0.0.1-prealpha.2"; export { PluginManifest0_0_1_prealpha_1, + PluginManifest0_0_1_prealpha_2, }; export enum PluginManifestFormats { "0.0.1-prealpha.1" = "0.0.1-prealpha.1", + "0.0.1-prealpha.2" = "0.0.1-prealpha.2", } export type AnyPluginManifest = | PluginManifest0_0_1_prealpha_1 + | PluginManifest0_0_1_prealpha_2 -export type PluginManifest = PluginManifest0_0_1_prealpha_1; +export type PluginManifest = PluginManifest0_0_1_prealpha_2; -export const latestPluginManifestFormat = PluginManifestFormats["0.0.1-prealpha.1"] +export const latestPluginManifestFormat = PluginManifestFormats["0.0.1-prealpha.2"] export { migratePluginManifest } from "./migrate"; diff --git a/packages/js/core/src/manifest/formats/web3api.plugin/migrate.ts b/packages/js/core/src/manifest/formats/web3api.plugin/migrate.ts index efc4ef2183..265dcf576c 100644 --- a/packages/js/core/src/manifest/formats/web3api.plugin/migrate.ts +++ b/packages/js/core/src/manifest/formats/web3api.plugin/migrate.ts @@ -11,6 +11,9 @@ import { latestPluginManifestFormat } from "."; +import { + migrate as migrate_0_0_1_prealpha_1_to_0_0_1_prealpha_2 +} from "./migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.2"; import { Tracer } from "@web3api/tracing-js"; @@ -19,6 +22,7 @@ type Migrator = { }; export const migrators: Migrator = { + "0.0.1-prealpha.1": migrate_0_0_1_prealpha_1_to_0_0_1_prealpha_2, }; export const migratePluginManifest = Tracer.traceFunc( @@ -34,6 +38,13 @@ export const migratePluginManifest = Tracer.traceFunc( throw new Error(`Unrecognized PluginManifestFormat "${manifest.format}"`); } - throw new Error(`This should never happen, PluginManifest migrators is empty. from: ${from}, to: ${to}`); + const migrator = migrators[from]; + if (!migrator) { + throw new Error( + `Migrator from PluginManifestFormat "${from}" to "${to}" is not available` + ); + } + + return migrator(manifest); } ); diff --git a/packages/js/core/src/manifest/formats/web3api.plugin/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.2.ts b/packages/js/core/src/manifest/formats/web3api.plugin/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.2.ts new file mode 100644 index 0000000000..849f465da3 --- /dev/null +++ b/packages/js/core/src/manifest/formats/web3api.plugin/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.2.ts @@ -0,0 +1 @@ +export const migrate = undefined; diff --git a/packages/js/core/src/manifest/formats/web3api.plugin/validate.ts b/packages/js/core/src/manifest/formats/web3api.plugin/validate.ts index ea169363b7..ac9997f5e7 100644 --- a/packages/js/core/src/manifest/formats/web3api.plugin/validate.ts +++ b/packages/js/core/src/manifest/formats/web3api.plugin/validate.ts @@ -11,6 +11,7 @@ import { import * as Validators from "../../validators"; import schema_0_0_1_prealpha_1 from "@web3api/manifest-schemas/formats/web3api.plugin/0.0.1-prealpha.1.json"; +import schema_0_0_1_prealpha_2 from "@web3api/manifest-schemas/formats/web3api.plugin/0.0.1-prealpha.2.json"; import { Tracer } from "@web3api/tracing-js" import { @@ -26,12 +27,15 @@ type PluginManifestSchemas = { const schemas: PluginManifestSchemas = { "0.0.1-prealpha.1": schema_0_0_1_prealpha_1, + "0.0.1-prealpha.2": schema_0_0_1_prealpha_2, }; const validator = new Validator(); Validator.prototype.customFormats.pluginLanguage = Validators.pluginLanguage; Validator.prototype.customFormats.file = Validators.file; +Validator.prototype.customFormats.packageName = Validators.packageName; +Validator.prototype.customFormats.graphqlFile = Validators.graphqlFile; export const validatePluginManifest = Tracer.traceFunc( "core: validatePluginManifest", diff --git a/packages/js/core/src/types/Api.ts b/packages/js/core/src/types/Api.ts index 66f935e63e..15238cee85 100644 --- a/packages/js/core/src/types/Api.ts +++ b/packages/js/core/src/types/Api.ts @@ -22,7 +22,7 @@ export abstract class Api { * @param client The client instance requesting this invocation. * This client will be used for any sub-queries that occur. */ - public abstract async invoke( + public abstract invoke( options: InvokeApiOptions, client: Client ): Promise>; @@ -32,7 +32,7 @@ export abstract class Api { * * @param client The client instance the schema. */ - public abstract async getSchema(client: Client): Promise; + public abstract getSchema(client: Client): Promise; /** * Get the API's manifest @@ -40,7 +40,7 @@ export abstract class Api { * @param options Configuration options for manifest retrieval * @param client The client instance requesting the manifest. */ - public abstract async getManifest< + public abstract getManifest< TManifestArtifactType extends ManifestArtifactType >( options: GetManifestOptions, @@ -54,7 +54,7 @@ export abstract class Api { * @param options Configuration options for file retrieval * @param client The client instance requesting the file. */ - public abstract async getFile( + public abstract getFile( options: GetFileOptions, client: Client ): Promise; diff --git a/packages/js/core/src/types/Plugin.ts b/packages/js/core/src/types/Plugin.ts index d6d3834fb2..9ff4d48cf6 100644 --- a/packages/js/core/src/types/Plugin.ts +++ b/packages/js/core/src/types/Plugin.ts @@ -1,4 +1,11 @@ -import { Uri, Client, InvokableModules, MaybeAsync } from "."; +/* eslint-disable @typescript-eslint/naming-convention */ +import { + Uri, + Client, + InvokableModules, + MaybeAsync, + executeMaybeAsyncFunction, +} from "."; /** * Invocable plugin method. @@ -8,66 +15,100 @@ import { Uri, Client, InvokableModules, MaybeAsync } from "."; * @param client The client instance requesting this invocation. * This client will be used for any sub-queries that occur. */ -export type PluginMethod = ( - input: Record, - client: Client -) => MaybeAsync; +export type PluginMethod< + TInput extends Record = Record, + TResult = unknown +> = (input: TInput, client: Client) => MaybeAsync; -/** - * A plugin "module" is a named map of [[PluginMethod | invocable methods]]. - * The names of these methods map 1:1 with the schema's query methods. - */ -export type PluginModule = Record; +export abstract class PluginModule< + TConfig extends Record = Record, + TEnv extends Record = Record, + TClientEnv extends Record = TEnv +> { + private _env: TEnv; + private _config: TConfig; -/** @ignore */ -type PluginModulesType = { - [module in InvokableModules]?: PluginModule; -}; + constructor(config: TConfig) { + this._config = config; + } + + public get env(): TEnv { + return this._env; + } + + public get config(): TConfig { + return this._config; + } + + public _w3_load_env(env: TEnv): void { + this._env = env; + } + + public async _w3_sanitize_env( + clientEnv: TClientEnv, + client: Client + ): Promise { + if (this.getMethod("sanitizeEnv")) { + return this._w3_invoke( + "sanitizeEnv", + clientEnv, + client + ); + } else { + return Promise.resolve(clientEnv as TEnv); + } + } + + public async _w3_invoke< + TInput extends Record = Record, + TResult = unknown + >(method: string, input: TInput, client: Client): Promise { + const fn = this.getMethod(method); + + if (!fn) { + throw Error("TODO: missing function"); + } + + if (typeof fn !== "function") { + throw Error("TODO: ${method} must be a function"); + } + + return await executeMaybeAsyncFunction( + fn.bind(this, input, client) + ); + } + + public getMethod< + TInput extends Record = Record, + TResult = unknown + >(method: string): PluginMethod | undefined { + const fn: + | PluginMethod + | undefined = ((this as unknown) as Record< + string, + PluginMethod + >)[method]; + + return fn; + } +} /** The plugin's query "modules" */ -export type PluginModules = PluginModulesType; +export type PluginModules = { + [module in InvokableModules]?: PluginModule; +}; /** * The plugin instance. */ -export abstract class Plugin { - private _env: Record> = { - query: {}, - mutation: {}, - }; +export interface Plugin { /** * Get an instance of this plugin's modules. * * @param client The client instance requesting the modules. * This client will be used for any sub-queries that occur. */ - public abstract getModules(client: Client): PluginModules; - - /** - * Sanitize plugin environment. - * This can optionally implemented by plugin - * - * @param env Module environment to be sanitized - */ - public sanitizeEnv?( - env: Record - ): Promise>; - - /** - * Load module enviroment to be used - * - * @param env module enviroment to be set inside plugin - */ - public loadEnv(env: Record, module: InvokableModules): void { - this._env[module] = env; - } - - /** - * Get module environment - */ - public getEnv(module: InvokableModules): Record { - return this._env[module]; - } + getModules(): PluginModules; } /** The plugin package's manifest */ diff --git a/packages/js/plugins/ens/package.json b/packages/js/plugins/ens/package.json index a16426e33f..efd4bb291f 100644 --- a/packages/js/plugins/ens/package.json +++ b/packages/js/plugins/ens/package.json @@ -9,11 +9,12 @@ }, "main": "build/index.js", "files": [ - "build", - "schema.graphql" + "build" ], "scripts": { - "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "build": "rimraf ./build ./**/w3 ./*/**/w3 && tsc --project tsconfig.build.json", + "build:migrate": "npx w3 plugin codegen", + "build:bak": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", "codegen": "node ../../../../dependencies/node_modules/@web3api/cli/bin/w3 plugin codegen", "lint": "eslint --color -c ../../../../.eslintrc.js src/", "test": "jest --passWithNoTests --runInBand --verbose", @@ -22,6 +23,7 @@ }, "dependencies": { "@ethersproject/address": "5.0.7", + "@ethersproject/basex": "5.0.7", "@web3api/core-js": "0.0.1-prealpha.71", "ethers": "5.0.7" }, diff --git a/packages/js/plugins/ens/src/index.ts b/packages/js/plugins/ens/src/index.ts index 6ffaa04a2c..a7af0fac7a 100644 --- a/packages/js/plugins/ens/src/index.ts +++ b/packages/js/plugins/ens/src/index.ts @@ -1,194 +1,3 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { query } from "./resolvers"; -import { manifest, Query, Ethereum_Query } from "./w3"; +// TIP: All user-defined code lives in the module folders (./query, ./mutation) -import { - Client, - Plugin, - PluginPackageManifest, - PluginFactory, -} from "@web3api/core-js"; -import { ethers } from "ethers"; -import { Base58 } from "@ethersproject/basex"; -import { getAddress } from "@ethersproject/address"; - -export type Address = string; - -export interface Addresses { - [network: string]: Address; -} - -export interface EnsConfig { - addresses?: Addresses; -} - -export class EnsPlugin extends Plugin { - public static defaultEnsAddress = - "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"; - - constructor(private _config: EnsConfig) { - super(); - - // Sanitize address - if (this._config.addresses) { - this.setAddresses(this._config.addresses); - } - } - - public static manifest(): PluginPackageManifest { - return manifest; - } - - public static isENSDomain(domain: string): boolean { - return ethers.utils.isValidName(domain) && domain.indexOf(".eth") !== -1; - } - - public getModules( - client: Client - ): { - query: Query.Module; - } { - return { - query: query(this, client), - }; - } - - public setAddresses(addresses: Addresses): void { - this._config.addresses = {}; - - for (const network of Object.keys(addresses)) { - this._config.addresses[network] = getAddress(addresses[network]); - } - } - - public async ensToCID(domain: string, client: Client): Promise { - const ensAbi = { - resolver: - "function resolver(bytes32 node) external view returns (address)", - }; - const resolverAbi = { - contenthash: - "function contenthash(bytes32 nodehash) view returns (bytes)", - content: "function content(bytes32 nodehash) view returns (bytes32)", - }; - - let ensAddress = EnsPlugin.defaultEnsAddress; - - // Remove the ENS URI scheme & authority - domain = domain.replace("w3://", ""); - domain = domain.replace("ens/", ""); - - // Check for non-default network - let network = "mainnet"; - const hasNetwork = /^[A-Za-z0-9]+\//i.exec(domain); - if (hasNetwork) { - network = domain.substring(0, domain.indexOf("/")); - - // Remove the network from the domain URI's path - domain = domain.replace(network + "/", ""); - - // Lowercase only - network = network.toLowerCase(); - - // Check if we have a custom address configured - // for this network - if (this._config.addresses && this._config.addresses[network]) { - ensAddress = this._config.addresses[network]; - } - } - - const domainNode = ethers.utils.namehash(domain); - - const callContractView = async ( - address: string, - method: string, - args: string[], - networkNameOrChainId?: string - ): Promise => { - const { data, error } = await Ethereum_Query.callContractView( - { - address, - method, - args, - connection: networkNameOrChainId - ? { - networkNameOrChainId, - } - : undefined, - }, - client - ); - - if (error) { - throw error; - } - - if (data) { - if (typeof data !== "string") { - throw Error( - `Malformed data returned from Ethereum.callContractView: ${data}` - ); - } - - return data; - } - - throw Error( - `Ethereum.callContractView returned nothing.\nData: ${data}\nError: ${error}` - ); - }; - - // Get the node's resolver address - const resolverAddress = await callContractView( - ensAddress, - ensAbi.resolver, - [domainNode], - network - ); - - // Get the CID stored at this domain - let hash; - try { - hash = await callContractView( - resolverAddress, - resolverAbi.contenthash, - [domainNode], - network - ); - } catch (e) { - try { - // Fallback, contenthash doesn't exist, try content - hash = await callContractView( - resolverAddress, - resolverAbi.content, - [domainNode], - network - ); - } catch (err) { - // The resolver contract is unknown... - throw Error(`Incompatible resolver ABI at address ${resolverAddress}`); - } - } - - if (hash === "0x") { - return ""; - } - - if ( - hash.substring(0, 10) === "0xe3010170" && - ethers.utils.isHexString(hash, 38) - ) { - return Base58.encode(ethers.utils.hexDataSlice(hash, 4)); - } else { - throw Error(`Unknown CID format, CID hash: ${hash}`); - } - } -} - -export const ensPlugin: PluginFactory = (opts: EnsConfig) => { - return { - factory: () => new EnsPlugin(opts), - manifest: manifest, - }; -}; -export const plugin = ensPlugin; +export * from "./w3-man"; diff --git a/packages/js/plugins/ens/src/query/index.ts b/packages/js/plugins/ens/src/query/index.ts new file mode 100644 index 0000000000..89396bdae4 --- /dev/null +++ b/packages/js/plugins/ens/src/query/index.ts @@ -0,0 +1,199 @@ +import { + Client, + Module, + Input_tryResolveUri, + Input_getFile, + UriResolver_MaybeUriOrManifest, + Bytes, + Ethereum_Query, +} from "./w3-man"; + +import { ethers } from "ethers"; +import { Base58 } from "@ethersproject/basex"; +import { getAddress } from "@ethersproject/address"; + +export type Address = string; + +export interface Addresses { + [network: string]: Address; +} + +export interface QueryConfig extends Record { + addresses?: Addresses; +} + +export class Query extends Module { + public static defaultEnsAddress = + "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"; + + constructor(config: QueryConfig) { + super(config); + + // Sanitize address + if (this.config.addresses) { + this._setAddresses(this.config.addresses); + } + } + + async tryResolveUri( + input: Input_tryResolveUri, + client: Client + ): Promise { + if (input.authority !== "ens") { + return null; + } + + try { + const cid = await this.ensToCID(input.path, client); + + if (!cid) { + return null; + } + + return { + uri: `ipfs/${cid}`, + manifest: null, + }; + } catch (e) { + // TODO: logging https://github.com/web3-api/monorepo/issues/33 + } + + // Nothing found + return { uri: null, manifest: null }; + } + + getFile(_input: Input_getFile, _client: Client): Bytes | null { + return null; + } + + async ensToCID(domain: string, client: Client): Promise { + const ensAbi = { + resolver: + "function resolver(bytes32 node) external view returns (address)", + }; + const resolverAbi = { + contenthash: + "function contenthash(bytes32 nodehash) view returns (bytes)", + content: "function content(bytes32 nodehash) view returns (bytes32)", + }; + + let ensAddress = Query.defaultEnsAddress; + + // Remove the ENS URI scheme & authority + domain = domain.replace("w3://", ""); + domain = domain.replace("ens/", ""); + + // Check for non-default network + let network = "mainnet"; + const hasNetwork = /^[A-Za-z0-9]+\//i.exec(domain); + if (hasNetwork) { + network = domain.substring(0, domain.indexOf("/")); + + // Remove the network from the domain URI's path + domain = domain.replace(network + "/", ""); + + // Lowercase only + network = network.toLowerCase(); + + // Check if we have a custom address configured + // for this network + if (this.config.addresses && this.config.addresses[network]) { + ensAddress = this.config.addresses[network]; + } + } + + const domainNode = ethers.utils.namehash(domain); + + const callContractView = async ( + address: string, + method: string, + args: string[], + networkNameOrChainId?: string + ): Promise => { + const { data, error } = await Ethereum_Query.callContractView( + { + address, + method, + args, + connection: networkNameOrChainId + ? { + networkNameOrChainId, + } + : undefined, + }, + client + ); + + if (error) { + throw error; + } + + if (data) { + if (typeof data !== "string") { + throw Error( + `Malformed data returned from Ethereum.callContractView: ${data}` + ); + } + + return data; + } + + throw Error( + `Ethereum.callContractView returned nothing.\nData: ${data}\nError: ${error}` + ); + }; + + // Get the node's resolver address + const resolverAddress = await callContractView( + ensAddress, + ensAbi.resolver, + [domainNode], + network + ); + + // Get the CID stored at this domain + let hash; + try { + hash = await callContractView( + resolverAddress, + resolverAbi.contenthash, + [domainNode], + network + ); + } catch (e) { + try { + // Fallback, contenthash doesn't exist, try content + hash = await callContractView( + resolverAddress, + resolverAbi.content, + [domainNode], + network + ); + } catch (err) { + // The resolver contract is unknown... + throw Error(`Incompatible resolver ABI at address ${resolverAddress}`); + } + } + + if (hash === "0x") { + return ""; + } + + if ( + hash.substring(0, 10) === "0xe3010170" && + ethers.utils.isHexString(hash, 38) + ) { + return Base58.encode(ethers.utils.hexDataSlice(hash, 4)); + } else { + throw Error(`Unknown CID format, CID hash: ${hash}`); + } + } + + private _setAddresses(addresses: Addresses): void { + this.config.addresses = {}; + + for (const network of Object.keys(addresses)) { + this.config.addresses[network] = getAddress(addresses[network]); + } + } +} diff --git a/packages/js/plugins/ens/schema.graphql b/packages/js/plugins/ens/src/query/schema.graphql similarity index 100% rename from packages/js/plugins/ens/schema.graphql rename to packages/js/plugins/ens/src/query/schema.graphql diff --git a/packages/js/plugins/ens/src/query/w3-man/index.ts b/packages/js/plugins/ens/src/query/w3-man/index.ts new file mode 100644 index 0000000000..6417838d60 --- /dev/null +++ b/packages/js/plugins/ens/src/query/w3-man/index.ts @@ -0,0 +1,4 @@ +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/core-js"; diff --git a/packages/js/plugins/ens/src/query/w3-man/module.ts b/packages/js/plugins/ens/src/query/w3-man/module.ts new file mode 100644 index 0000000000..08d098fa52 --- /dev/null +++ b/packages/js/plugins/ens/src/query/w3-man/module.ts @@ -0,0 +1,33 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as Types from "./types"; + +import { Client, PluginModule, MaybeAsync } from "@web3api/core-js"; + +export interface Input_tryResolveUri extends Record { + authority: Types.String; + path: Types.String; +} + +export interface Input_getFile extends Record { + path: Types.String; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule { + constructor(config: TConfig) { + super(config); + } + + abstract tryResolveUri( + input: Input_tryResolveUri, + client: Client + ): MaybeAsync; + + abstract getFile( + input: Input_getFile, + client: Client + ): MaybeAsync; +} diff --git a/packages/cli/src/__tests__/plugin/expected-types/types.ts b/packages/js/plugins/ens/src/query/w3-man/types.ts similarity index 55% rename from packages/cli/src/__tests__/plugin/expected-types/types.ts rename to packages/js/plugins/ens/src/query/w3-man/types.ts index b1f50e5f59..bc8baca508 100644 --- a/packages/cli/src/__tests__/plugin/expected-types/types.ts +++ b/packages/js/plugins/ens/src/query/w3-man/types.ts @@ -1,10 +1,12 @@ -// @ts-noCheck +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +// @ts-ignore import * as Types from "./"; -import { - Client, - InvokeApiResult -} from "@web3api/core-js"; +// @ts-ignore +import { Client, InvokeApiResult } from "@web3api/core-js"; export type UInt = number; export type UInt8 = number; @@ -21,18 +23,18 @@ export type Json = string; export type String = string; export type Boolean = boolean; -export interface Object { - u: UInt; - array: Array; - bytes?: Bytes | null; -} - /// Imported Objects START /// +/* URI: "ens/uri-resolver.core.web3api.eth" */ +export interface UriResolver_MaybeUriOrManifest { + uri?: string | null; + manifest?: string | null; +} + /* URI: "ens/ethereum.web3api.eth" */ export interface Ethereum_Connection { - node?: String | null; - networkNameOrChainId?: String | null; + node?: string | null; + networkNameOrChainId?: string | null; } /* URI: "ens/ethereum.web3api.eth" */ @@ -44,18 +46,18 @@ export interface Ethereum_TxOverrides { /* URI: "ens/ethereum.web3api.eth" */ export interface Ethereum_StaticTxResult { - result: String; - error: Boolean; + result: string; + error: boolean; } /* URI: "ens/ethereum.web3api.eth" */ export interface Ethereum_TxRequest { - to?: String | null; - from?: String | null; + to?: string | null; + from?: string | null; nonce?: UInt32 | null; gasLimit?: BigInt | null; gasPrice?: BigInt | null; - data?: String | null; + data?: string | null; value?: BigInt | null; chainId?: BigInt | null; type?: UInt32 | null; @@ -63,21 +65,21 @@ export interface Ethereum_TxRequest { /* URI: "ens/ethereum.web3api.eth" */ export interface Ethereum_TxReceipt { - to: String; - from: String; - contractAddress: String; + to: string; + from: string; + contractAddress: string; transactionIndex: UInt32; - root?: String | null; + root?: string | null; gasUsed: BigInt; - logsBloom: String; - transactionHash: String; + logsBloom: string; + transactionHash: string; logs: Array; blockNumber: BigInt; - blockHash: String; + blockHash: string; confirmations: UInt32; cumulativeGasUsed: BigInt; effectiveGasPrice: BigInt; - byzantium: Boolean; + byzantium: boolean; type: UInt32; status?: UInt32 | null; } @@ -85,130 +87,146 @@ export interface Ethereum_TxReceipt { /* URI: "ens/ethereum.web3api.eth" */ export interface Ethereum_Log { blockNumber: BigInt; - blockHash: String; + blockHash: string; transactionIndex: UInt32; - removed: Boolean; - address: String; - data: String; - topics: Array; - transactionHash: String; + removed: boolean; + address: string; + data: string; + topics: Array; + transactionHash: string; logIndex: UInt32; } /* URI: "ens/ethereum.web3api.eth" */ export interface Ethereum_EventNotification { - data: String; - address: String; + data: string; + address: string; log: Types.Ethereum_Log; } /* URI: "ens/ethereum.web3api.eth" */ export interface Ethereum_Network { - name: String; + name: string; chainId: BigInt; - ensAddress?: String | null; + ensAddress?: string | null; } -/* URI: "ens/ethereum.web3api.eth" */ -export interface Ethereum_TxResponse { - hash: String; - to?: String | null; - from: String; - nonce: UInt32; - gasLimit: BigInt; - gasPrice?: BigInt | null; - data: String; - value: BigInt; - chainId: BigInt; - blockNumber?: BigInt | null; - blockHash?: String | null; - timestamp?: UInt32 | null; - confirmations: UInt32; - raw?: String | null; - r?: String | null; - s?: String | null; - v?: UInt32 | null; - type?: UInt32 | null; - accessList?: Array | null; +/// Imported Objects END /// + +/// Imported Queries START /// + +/* URI: "ens/uri-resolver.core.web3api.eth" */ +interface UriResolver_Query_Input_tryResolveUri + extends Record { + authority: string; + path: string; } -/* URI: "ens/ethereum.web3api.eth" */ -export interface Ethereum_Access { - address: String; - storageKeys: Array; +/* URI: "ens/uri-resolver.core.web3api.eth" */ +interface UriResolver_Query_Input_getFile extends Record { + path: string; } -/// Imported Objects END /// +/* URI: "ens/uri-resolver.core.web3api.eth" */ +export const UriResolver_Query = { + tryResolveUri: async ( + input: UriResolver_Query_Input_tryResolveUri, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/uri-resolver.core.web3api.eth", + module: "query", + method: "tryResolveUri", + input, + }); + }, -/// Imported Queries START /// + getFile: async ( + input: UriResolver_Query_Input_getFile, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/uri-resolver.core.web3api.eth", + module: "query", + method: "getFile", + input, + }); + }, +}; /* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Query_Input_callContractView extends Record { - address: String; - method: String; - args?: Array | null; +interface Ethereum_Query_Input_callContractView + extends Record { + address: string; + method: string; + args?: Array | null; connection?: Types.Ethereum_Connection | null; } /* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Query_Input_callContractStatic extends Record { - address: String; - method: String; - args?: Array | null; +interface Ethereum_Query_Input_callContractStatic + extends Record { + address: string; + method: string; + args?: Array | null; connection?: Types.Ethereum_Connection | null; txOverrides?: Types.Ethereum_TxOverrides | null; } /* URI: "ens/ethereum.web3api.eth" */ interface Ethereum_Query_Input_getBalance extends Record { - address: String; + address: string; blockTag?: BigInt | null; connection?: Types.Ethereum_Connection | null; } /* URI: "ens/ethereum.web3api.eth" */ interface Ethereum_Query_Input_encodeParams extends Record { - types: Array; - values: Array; + types: Array; + values: Array; } /* URI: "ens/ethereum.web3api.eth" */ interface Ethereum_Query_Input_encodeFunction extends Record { - method: String; - args?: Array | null; + method: string; + args?: Array | null; } /* URI: "ens/ethereum.web3api.eth" */ interface Ethereum_Query_Input_solidityPack extends Record { - types: Array; - values: Array; + types: Array; + values: Array; } /* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Query_Input_solidityKeccak256 extends Record { - types: Array; - values: Array; +interface Ethereum_Query_Input_solidityKeccak256 + extends Record { + types: Array; + values: Array; } /* URI: "ens/ethereum.web3api.eth" */ interface Ethereum_Query_Input_soliditySha256 extends Record { - types: Array; - values: Array; + types: Array; + values: Array; } /* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Query_Input_getSignerAddress extends Record { +interface Ethereum_Query_Input_getSignerAddress + extends Record { connection?: Types.Ethereum_Connection | null; } /* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Query_Input_getSignerBalance extends Record { +interface Ethereum_Query_Input_getSignerBalance + extends Record { blockTag?: BigInt | null; connection?: Types.Ethereum_Connection | null; } /* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Query_Input_getSignerTransactionCount extends Record { +interface Ethereum_Query_Input_getSignerTransactionCount + extends Record { blockTag?: BigInt | null; connection?: Types.Ethereum_Connection | null; } @@ -219,28 +237,30 @@ interface Ethereum_Query_Input_getGasPrice extends Record { } /* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Query_Input_estimateTransactionGas extends Record { +interface Ethereum_Query_Input_estimateTransactionGas + extends Record { tx: Types.Ethereum_TxRequest; connection?: Types.Ethereum_Connection | null; } /* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Query_Input_estimateContractCallGas extends Record { - address: String; - method: String; - args?: Array | null; +interface Ethereum_Query_Input_estimateContractCallGas + extends Record { + address: string; + method: string; + args?: Array | null; connection?: Types.Ethereum_Connection | null; txOverrides?: Types.Ethereum_TxOverrides | null; } /* URI: "ens/ethereum.web3api.eth" */ interface Ethereum_Query_Input_checkAddress extends Record { - address: String; + address: string; } /* URI: "ens/ethereum.web3api.eth" */ interface Ethereum_Query_Input_toWei extends Record { - eth: String; + eth: string; } /* URI: "ens/ethereum.web3api.eth" */ @@ -249,8 +269,9 @@ interface Ethereum_Query_Input_toEth extends Record { } /* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Query_Input_awaitTransaction extends Record { - txHash: String; +interface Ethereum_Query_Input_awaitTransaction + extends Record { + txHash: string; confirmations: UInt32; timeout: UInt32; connection?: Types.Ethereum_Connection | null; @@ -258,9 +279,9 @@ interface Ethereum_Query_Input_awaitTransaction extends Record /* URI: "ens/ethereum.web3api.eth" */ interface Ethereum_Query_Input_waitForEvent extends Record { - address: String; - event: String; - args?: Array | null; + address: string; + event: string; + args?: Array | null; timeout?: UInt32 | null; connection?: Types.Ethereum_Connection | null; } @@ -275,12 +296,12 @@ export const Ethereum_Query = { callContractView: async ( input: Ethereum_Query_Input_callContractView, client: Client - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri: "ens/ethereum.web3api.eth", module: "query", method: "callContractView", - input + input, }); }, @@ -292,7 +313,7 @@ export const Ethereum_Query = { uri: "ens/ethereum.web3api.eth", module: "query", method: "callContractStatic", - input + input, }); }, @@ -304,79 +325,79 @@ export const Ethereum_Query = { uri: "ens/ethereum.web3api.eth", module: "query", method: "getBalance", - input + input, }); }, encodeParams: async ( input: Ethereum_Query_Input_encodeParams, client: Client - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri: "ens/ethereum.web3api.eth", module: "query", method: "encodeParams", - input + input, }); }, encodeFunction: async ( input: Ethereum_Query_Input_encodeFunction, client: Client - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri: "ens/ethereum.web3api.eth", module: "query", method: "encodeFunction", - input + input, }); }, solidityPack: async ( input: Ethereum_Query_Input_solidityPack, client: Client - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri: "ens/ethereum.web3api.eth", module: "query", method: "solidityPack", - input + input, }); }, solidityKeccak256: async ( input: Ethereum_Query_Input_solidityKeccak256, client: Client - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri: "ens/ethereum.web3api.eth", module: "query", method: "solidityKeccak256", - input + input, }); }, soliditySha256: async ( input: Ethereum_Query_Input_soliditySha256, client: Client - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri: "ens/ethereum.web3api.eth", module: "query", method: "soliditySha256", - input + input, }); }, getSignerAddress: async ( input: Ethereum_Query_Input_getSignerAddress, client: Client - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri: "ens/ethereum.web3api.eth", module: "query", method: "getSignerAddress", - input + input, }); }, @@ -388,7 +409,7 @@ export const Ethereum_Query = { uri: "ens/ethereum.web3api.eth", module: "query", method: "getSignerBalance", - input + input, }); }, @@ -400,7 +421,7 @@ export const Ethereum_Query = { uri: "ens/ethereum.web3api.eth", module: "query", method: "getSignerTransactionCount", - input + input, }); }, @@ -412,7 +433,7 @@ export const Ethereum_Query = { uri: "ens/ethereum.web3api.eth", module: "query", method: "getGasPrice", - input + input, }); }, @@ -424,7 +445,7 @@ export const Ethereum_Query = { uri: "ens/ethereum.web3api.eth", module: "query", method: "estimateTransactionGas", - input + input, }); }, @@ -436,19 +457,19 @@ export const Ethereum_Query = { uri: "ens/ethereum.web3api.eth", module: "query", method: "estimateContractCallGas", - input + input, }); }, checkAddress: async ( input: Ethereum_Query_Input_checkAddress, client: Client - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri: "ens/ethereum.web3api.eth", module: "query", method: "checkAddress", - input + input, }); }, @@ -460,19 +481,19 @@ export const Ethereum_Query = { uri: "ens/ethereum.web3api.eth", module: "query", method: "toWei", - input + input, }); }, toEth: async ( input: Ethereum_Query_Input_toEth, client: Client - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri: "ens/ethereum.web3api.eth", module: "query", method: "toEth", - input + input, }); }, @@ -484,7 +505,7 @@ export const Ethereum_Query = { uri: "ens/ethereum.web3api.eth", module: "query", method: "awaitTransaction", - input + input, }); }, @@ -496,7 +517,7 @@ export const Ethereum_Query = { uri: "ens/ethereum.web3api.eth", module: "query", method: "waitForEvent", - input + input, }); }, @@ -508,150 +529,9 @@ export const Ethereum_Query = { uri: "ens/ethereum.web3api.eth", module: "query", method: "getNetwork", - input - }); - } -} - - -/* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Mutation_Input_callContractMethod extends Record { - address: String; - method: String; - args?: Array | null; - connection?: Types.Ethereum_Connection | null; - txOverrides?: Types.Ethereum_TxOverrides | null; -} - -/* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Mutation_Input_callContractMethodAndWait extends Record { - address: String; - method: String; - args?: Array | null; - connection?: Types.Ethereum_Connection | null; - txOverrides?: Types.Ethereum_TxOverrides | null; -} - -/* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Mutation_Input_sendTransaction extends Record { - tx: Types.Ethereum_TxRequest; - connection?: Types.Ethereum_Connection | null; -} - -/* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Mutation_Input_sendTransactionAndWait extends Record { - tx: Types.Ethereum_TxRequest; - connection?: Types.Ethereum_Connection | null; -} - -/* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Mutation_Input_deployContract extends Record { - abi: String; - bytecode: String; - args?: Array | null; - connection?: Types.Ethereum_Connection | null; -} - -/* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Mutation_Input_signMessage extends Record { - message: String; - connection?: Types.Ethereum_Connection | null; -} - -/* URI: "ens/ethereum.web3api.eth" */ -interface Ethereum_Mutation_Input_sendRPC extends Record { - method: String; - params: Array; - connection?: Types.Ethereum_Connection | null; -} - -/* URI: "ens/ethereum.web3api.eth" */ -export const Ethereum_Mutation = { - callContractMethod: async ( - input: Ethereum_Mutation_Input_callContractMethod, - client: Client - ): Promise> => { - return client.invoke({ - uri: "ens/ethereum.web3api.eth", - module: "mutation", - method: "callContractMethod", - input - }); - }, - - callContractMethodAndWait: async ( - input: Ethereum_Mutation_Input_callContractMethodAndWait, - client: Client - ): Promise> => { - return client.invoke({ - uri: "ens/ethereum.web3api.eth", - module: "mutation", - method: "callContractMethodAndWait", - input - }); - }, - - sendTransaction: async ( - input: Ethereum_Mutation_Input_sendTransaction, - client: Client - ): Promise> => { - return client.invoke({ - uri: "ens/ethereum.web3api.eth", - module: "mutation", - method: "sendTransaction", - input - }); - }, - - sendTransactionAndWait: async ( - input: Ethereum_Mutation_Input_sendTransactionAndWait, - client: Client - ): Promise> => { - return client.invoke({ - uri: "ens/ethereum.web3api.eth", - module: "mutation", - method: "sendTransactionAndWait", - input - }); - }, - - deployContract: async ( - input: Ethereum_Mutation_Input_deployContract, - client: Client - ): Promise> => { - return client.invoke({ - uri: "ens/ethereum.web3api.eth", - module: "mutation", - method: "deployContract", - input + input, }); }, - - signMessage: async ( - input: Ethereum_Mutation_Input_signMessage, - client: Client - ): Promise> => { - return client.invoke({ - uri: "ens/ethereum.web3api.eth", - module: "mutation", - method: "signMessage", - input - }); - }, - - sendRPC: async ( - input: Ethereum_Mutation_Input_sendRPC, - client: Client - ): Promise> => { - return client.invoke({ - uri: "ens/ethereum.web3api.eth", - module: "mutation", - method: "sendRPC", - input - }); - } -} - +}; /// Imported Queries END /// - diff --git a/packages/js/plugins/ens/src/resolvers.ts b/packages/js/plugins/ens/src/resolvers.ts deleted file mode 100644 index 751bf66658..0000000000 --- a/packages/js/plugins/ens/src/resolvers.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { EnsPlugin } from "./"; -import { Query } from "./w3"; - -import { Client } from "@web3api/core-js"; - -export const query = (ens: EnsPlugin, client: Client): Query.Module => ({ - // uri-resolver.core.web3api.eth - tryResolveUri: async (input: Query.Input_tryResolveUri) => { - if (input.authority !== "ens") { - return null; - } - - try { - const cid = await ens.ensToCID(input.path, client); - - if (!cid) { - return null; - } - - return { - uri: `ipfs/${cid}`, - manifest: null, - }; - } catch (e) { - // TODO: logging https://github.com/web3-api/monorepo/issues/33 - } - - // Nothing found - return { uri: null, manifest: null }; - }, - getFile: (_input: Query.Input_getFile) => { - return null; - }, -}); diff --git a/packages/js/plugins/ens/src/w3-man/index.ts b/packages/js/plugins/ens/src/w3-man/index.ts new file mode 100644 index 0000000000..b4849fdac4 --- /dev/null +++ b/packages/js/plugins/ens/src/w3-man/index.ts @@ -0,0 +1,3 @@ +export * from "./schema"; +export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/js/plugins/ens/src/w3-man/manifest.ts b/packages/js/plugins/ens/src/w3-man/manifest.ts new file mode 100644 index 0000000000..278a2d0d7f --- /dev/null +++ b/packages/js/plugins/ens/src/w3-man/manifest.ts @@ -0,0 +1,15 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +import { schema } from "./"; + +// @ts-ignore +import { PluginPackageManifest, Uri } from "@web3api/core-js"; + +export const manifest: PluginPackageManifest = { + schema, + implements: [new Uri("ens/uri-resolver.core.web3api.eth")], +}; diff --git a/packages/js/plugins/ens/src/w3-man/plugin.ts b/packages/js/plugins/ens/src/w3-man/plugin.ts new file mode 100644 index 0000000000..0e4c67d9f6 --- /dev/null +++ b/packages/js/plugins/ens/src/w3-man/plugin.ts @@ -0,0 +1,41 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { Query, QueryConfig } from "../query"; +import { manifest } from "./manifest"; + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; + +export interface EnsPluginConfigs { + query: QueryConfig; +} + +export class EnsPlugin implements Plugin { + constructor(private _configs: EnsPluginConfigs) {} + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + query: new Query(this._configs.query), + }; + } +} + +export const ensPlugin: PluginFactory = ( + opts: EnsPluginConfigs +) => { + return { + factory: () => new EnsPlugin(opts), + manifest: manifest, + }; +}; + +export const plugin = ensPlugin; diff --git a/packages/js/plugins/ens/src/w3-man/schema.ts b/packages/js/plugins/ens/src/w3-man/schema.ts new file mode 100644 index 0000000000..c184ba5580 --- /dev/null +++ b/packages/js/plugins/ens/src/w3-man/schema.ts @@ -0,0 +1,314 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export const schema = `### 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 implements UriResolver_Query @imports( + types: [ + "UriResolver_Query", + "UriResolver_MaybeUriOrManifest", + "Ethereum_Query", + "Ethereum_Connection", + "Ethereum_TxOverrides", + "Ethereum_StaticTxResult", + "Ethereum_TxRequest", + "Ethereum_TxReceipt", + "Ethereum_Log", + "Ethereum_EventNotification", + "Ethereum_Network" + ] +) { + tryResolveUri( + authority: String! + path: String! + ): UriResolver_MaybeUriOrManifest + + getFile( + path: String! + ): Bytes +} + +### Imported Queries START ### + +type UriResolver_Query @imported( + uri: "ens/uri-resolver.core.web3api.eth", + namespace: "UriResolver", + nativeType: "Query" +) { + tryResolveUri( + authority: String! + path: String! + ): UriResolver_MaybeUriOrManifest + + getFile( + path: String! + ): Bytes +} + +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 UriResolver_MaybeUriOrManifest @imported( + uri: "ens/uri-resolver.core.web3api.eth", + namespace: "UriResolver", + nativeType: "MaybeUriOrManifest" +) { + uri: String + manifest: String +} + +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/js/plugins/ens/web3api.plugin.yaml b/packages/js/plugins/ens/web3api.plugin.yaml index fdc1da92f3..dd651426d9 100644 --- a/packages/js/plugins/ens/web3api.plugin.yaml +++ b/packages/js/plugins/ens/web3api.plugin.yaml @@ -1,6 +1,10 @@ -format: 0.0.1-prealpha.1 +format: 0.0.1-prealpha.2 language: plugin/typescript -schema: ./schema.graphql +name: Ens +modules: + query: + module: ./src/query/index.ts + schema: ./src/query/schema.graphql import_redirects: - uri: "ens/uri-resolver.core.web3api.eth" schema: ../../../core-interfaces/uri-resolver/src/query.graphql diff --git a/packages/js/plugins/ethereum/package.json b/packages/js/plugins/ethereum/package.json index 881e79615a..a18bb6d84e 100644 --- a/packages/js/plugins/ethereum/package.json +++ b/packages/js/plugins/ethereum/package.json @@ -9,11 +9,12 @@ }, "main": "build/index.js", "files": [ - "build", - "schema.graphql" + "build" ], "scripts": { - "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "build": "rimraf ./build ./**/w3 ./*/**/w3 && tsc --project tsconfig.build.json", + "build:migrate": "npx w3 plugin codegen", + "build:bak": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", "codegen": "node ../../../../dependencies/node_modules/@web3api/cli/bin/w3 plugin codegen", "lint": "eslint --color -c ../../../../.eslintrc.js src/", "test": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts b/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts index fa712f6bad..10d738d310 100644 --- a/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts +++ b/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts @@ -1,5 +1,5 @@ import { ethereumPlugin } from ".."; -import * as Schema from "../w3"; +import * as Schema from "../query/w3-man"; import { Web3ApiClient, defaultIpfsProviders } from "@web3api/client-js"; import { ensPlugin } from "@web3api/ens-plugin-js"; @@ -69,8 +69,10 @@ describe("Ethereum Plugin", () => { { uri: "w3://ens/ens.web3api.eth", plugin: ensPlugin({ - addresses: { - testnet: ensAddress + query: { + addresses: { + testnet: ensAddress + } } }) } @@ -162,7 +164,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 () => { diff --git a/packages/js/plugins/ethereum/src/Connection.ts b/packages/js/plugins/ethereum/src/common/Connection.ts similarity index 73% rename from packages/js/plugins/ethereum/src/Connection.ts rename to packages/js/plugins/ethereum/src/common/Connection.ts index f537293190..60f3ea291b 100644 --- a/packages/js/plugins/ethereum/src/Connection.ts +++ b/packages/js/plugins/ethereum/src/common/Connection.ts @@ -1,3 +1,5 @@ +import { Connection as SchemaConnection } from "../query/w3-man"; + import { Signer, ethers } from "ethers"; import { ExternalProvider, @@ -163,3 +165,59 @@ export class Connection { } } } + +export async function getConnection( + connections: Connections, + defaultNetwork: string, + connection?: SchemaConnection | null +): Promise { + if (!connection) { + return connections[defaultNetwork]; + } + + const { networkNameOrChainId, node } = connection; + let result: Connection; + + // If a custom network is provided, either get an already + // established connection, or a create a new one + if (networkNameOrChainId) { + const networkStr = networkNameOrChainId.toLowerCase(); + if (connections[networkStr]) { + result = connections[networkStr]; + } else { + const chainId = Number.parseInt(networkStr); + + if (!isNaN(chainId)) { + result = Connection.fromNetwork(chainId); + } else { + result = Connection.fromNetwork(networkStr); + } + } + } else { + result = connections[defaultNetwork]; + } + + // If a custom node endpoint is provided, create a combined + // connection with the node's endpoint and a connection's signer + // (if one exists for the network) + if (node) { + const nodeConnection = Connection.fromNode(node); + const nodeNetwork = await nodeConnection.getProvider().getNetwork(); + + const establishedConnection = + connections[nodeNetwork.chainId.toString()] || + connections[nodeNetwork.name]; + + if (establishedConnection) { + try { + nodeConnection.setSigner(establishedConnection.getSigner()); + } catch (e) { + // It's okay if there isn't a signer available. + } + } + + result = nodeConnection; + } + + return result; +} diff --git a/packages/js/plugins/ethereum/src/common/EthereumConfig.ts b/packages/js/plugins/ethereum/src/common/EthereumConfig.ts new file mode 100644 index 0000000000..3075c934e4 --- /dev/null +++ b/packages/js/plugins/ethereum/src/common/EthereumConfig.ts @@ -0,0 +1,6 @@ +import { ConnectionConfigs } from "./Connection"; + +export interface EthereumConfig { + networks: ConnectionConfigs; + defaultNetwork?: string; +} diff --git a/packages/js/plugins/ethereum/src/mapping.ts b/packages/js/plugins/ethereum/src/common/mapping.ts similarity index 99% rename from packages/js/plugins/ethereum/src/mapping.ts rename to packages/js/plugins/ethereum/src/common/mapping.ts index 0b97c5d8fb..4e077ee654 100644 --- a/packages/js/plugins/ethereum/src/mapping.ts +++ b/packages/js/plugins/ethereum/src/common/mapping.ts @@ -1,4 +1,4 @@ -import { Access, TxReceipt, TxResponse, TxRequest, Log } from "./w3"; +import { Access, TxReceipt, TxResponse, TxRequest, Log } from "../query/w3-man"; import { ethers } from "ethers"; diff --git a/packages/js/plugins/ethereum/src/common/parsing.ts b/packages/js/plugins/ethereum/src/common/parsing.ts new file mode 100644 index 0000000000..fadaad22f0 --- /dev/null +++ b/packages/js/plugins/ethereum/src/common/parsing.ts @@ -0,0 +1,12 @@ +export function parseArgs(args?: string[] | null): unknown[] { + if (!args) { + return []; + } + + return args.map((arg: string) => + (arg.startsWith("[") && arg.endsWith("]")) || + (arg.startsWith("{") && arg.endsWith("}")) + ? JSON.parse(arg) + : arg + ); +} diff --git a/packages/js/plugins/ethereum/src/common/schema.graphql b/packages/js/plugins/ethereum/src/common/schema.graphql new file mode 100644 index 0000000000..cd1e0c2089 --- /dev/null +++ b/packages/js/plugins/ethereum/src/common/schema.graphql @@ -0,0 +1,98 @@ +type TxReceipt { + to: String! + from: String! + contractAddress: String! + transactionIndex: UInt32! + root: String + gasUsed: BigInt! + logsBloom: String! + transactionHash: String! + logs: [Log!]! + blockNumber: BigInt! + blockHash: String! + confirmations: UInt32! + cumulativeGasUsed: BigInt! + effectiveGasPrice: BigInt! + byzantium: Boolean! + type: UInt32! + status: UInt32 +} + +type 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: [Access!] +} + +type TxRequest { + to: String + from: String + nonce: UInt32 + gasLimit: BigInt + gasPrice: BigInt + data: String + value: BigInt + chainId: BigInt + type: UInt32 +} + +type TxOverrides { + gasLimit: BigInt + gasPrice: BigInt + value: BigInt +} + +type StaticTxResult { + result: String! + error: Boolean! +} + +type Log { + blockNumber: BigInt! + blockHash: String! + transactionIndex: UInt32! + removed: Boolean! + address: String! + data: String! + topics: [String!]! + transactionHash: String! + logIndex: UInt32! +} + +type EventNotification { + data: String! + address: String! + log: Log! +} + +type Access { + address: String! + storageKeys: [String!]! +} + +type Connection { + node: String + networkNameOrChainId: String +} + +type Network { + name: String! + chainId: BigInt! + ensAddress: String +} diff --git a/packages/js/plugins/ethereum/src/index.ts b/packages/js/plugins/ethereum/src/index.ts index 54e2fe4653..1c5d794ce7 100644 --- a/packages/js/plugins/ethereum/src/index.ts +++ b/packages/js/plugins/ethereum/src/index.ts @@ -1,483 +1,31 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { query, mutation } from "./resolvers"; -import { manifest, Query, Mutation } from "./w3"; -import * as Types from "./w3"; -import { - Address, - AccountIndex, - EthereumSigner, - EthereumProvider, - Connection, - Connections, - ConnectionConfig, - ConnectionConfigs, -} from "./Connection"; -import * as Mapping from "./mapping"; +// TIP: All user-defined code lives in the module folders (./query, ./mutation) -import { - Client, - Plugin, - PluginPackageManifest, - PluginFactory, -} from "@web3api/core-js"; -import { ethers } from "ethers"; -import { defaultAbiCoder } from "ethers/lib/utils"; +import * as Internal from "./w3-man"; +import { EthereumConfig } from "./common/EthereumConfig"; -// Export all types that are nested inside of EthereumConfig. -// This is required for the extractPluginConfigs.ts script. -export { - Address, - AccountIndex, - EthereumSigner, - EthereumProvider, - ConnectionConfig, - ConnectionConfigs, -}; +import { PluginFactory } from "@web3api/core-js"; -export interface EthereumConfig { - networks: ConnectionConfigs; - defaultNetwork?: string; -} - -export class EthereumPlugin extends Plugin { - private _connections: Connections; - private _defaultNetwork: string; - - constructor(config: EthereumConfig) { - super(); - this._connections = Connection.fromConfigs(config.networks); - - // Assign the default network (mainnet if not provided) - if (config.defaultNetwork) { - this._defaultNetwork = config.defaultNetwork; - } else { - this._defaultNetwork = "mainnet"; - } - - // Create a connection for the default network if none exists - if (!this._connections[this._defaultNetwork]) { - this._connections[this._defaultNetwork] = Connection.fromNetwork( - this._defaultNetwork - ); - } - } - - public static manifest(): PluginPackageManifest { - return manifest; - } - - public getModules( - _client: Client - ): { - query: Query.Module; - mutation: Mutation.Module; - } { - return { - query: query(this), - mutation: mutation(this), - }; - } - - /// Mutation - - public async callContractMethod( - input: Mutation.Input_callContractMethod - ): Promise { - const res = await this._callContractMethod(input); - return Mapping.toTxResponse(res); - } - - public async callContractMethodAndWait( - input: Mutation.Input_callContractMethodAndWait - ): Promise { - const response = await this._callContractMethod(input); - const res = await response.wait(); - return Mapping.toTxReceipt(res); - } - - public async sendTransaction( - input: Mutation.Input_sendTransaction - ): Promise { - const connection = await this.getConnection(input.connection); - const signer = connection.getSigner(); - const res = await signer.sendTransaction(Mapping.fromTxRequest(input.tx)); - return Mapping.toTxResponse(res); - } - - public async sendTransactionAndWait( - input: Mutation.Input_sendTransactionAndWait - ): Promise { - const connection = await this.getConnection(input.connection); - const signer = connection.getSigner(); - const response = await signer.sendTransaction( - Mapping.fromTxRequest(input.tx) - ); - const receipt = await response.wait(); - return Mapping.toTxReceipt(receipt); - } - - public async deployContract( - input: Mutation.Input_deployContract - ): Promise { - const connection = await this.getConnection(input.connection); - const signer = connection.getSigner(); - const factory = new ethers.ContractFactory( - input.abi, - input.bytecode, - signer - ); - const contract = await factory.deploy(...this.parseArgs(input.args)); - - await contract.deployTransaction.wait(); - return contract.address; - } - - public async signMessage(input: Mutation.Input_signMessage): Promise { - const connection = await this.getConnection(input.connection); - return await connection.getSigner().signMessage(input.message); - } +export { manifest, schema } from "./w3-man"; - public async sendRPC(input: Mutation.Input_sendRPC): Promise { - const connection = await this.getConnection(input.connection); - const provider = connection.getProvider(); - const response = await provider.send(input.method, input.params); - return response.toString(); - } - - /// Query - - public async getNetwork( - input: Query.Input_getNetwork - ): Promise { - const connection = await this.getConnection(input.connection); - const provider = connection.getProvider(); - const network = await provider.getNetwork(); - return { - name: network.name, - chainId: network.chainId.toString(), - ensAddress: network.ensAddress, - }; - } - - public async callContractView( - input: Query.Input_callContractView - ): Promise { - const connection = await this.getConnection(input.connection); - const contract = connection.getContract( - input.address, - [input.method], - false - ); - const funcs = Object.keys(contract.interface.functions); - const res = await contract[funcs[0]](...this.parseArgs(input.args)); - return res.toString(); - } - - public async callContractStatic( - input: Query.Input_callContractStatic - ): Promise { - const connection = await this.getConnection(input.connection); - const contract = connection.getContract(input.address, [input.method]); - const funcs = Object.keys(contract.interface.functions); - - try { - const res = await contract.callStatic[funcs[0]]( - ...this.parseArgs(input.args), - { - gasPrice: input.gasPrice - ? ethers.BigNumber.from(input.gasPrice) - : undefined, - gasLimit: input.gasLimit - ? ethers.BigNumber.from(input.gasLimit) - : undefined, - value: input.value ? ethers.BigNumber.from(input.value) : undefined, - } - ); - return { - result: res.toString(), - error: false, - }; - } catch (e) { - return { - result: e.reason, - error: true, - }; - } - } - - public async getBalance(input: Query.Input_getBalance): Promise { - const connection = await this.getConnection(input.connection); - return ( - await connection - .getProvider() - .getBalance(input.address, input.blockTag || undefined) - ).toString(); - } - - public encodeParams(input: Query.Input_encodeParams): string { - return defaultAbiCoder.encode(input.types, this.parseArgs(input.values)); - } - - public encodeFunction(input: Query.Input_encodeFunction): string { - const functionInterface = ethers.Contract.getInterface([input.method]); - return functionInterface.encodeFunctionData( - functionInterface.functions[Object.keys(functionInterface.functions)[0]], - this.parseArgs(input.args) - ); - } - - public solidityPack(input: Query.Input_solidityPack): string { - return ethers.utils.solidityPack(input.types, this.parseArgs(input.values)); - } - - public solidityKeccak256(input: Query.Input_solidityKeccak256): string { - return ethers.utils.solidityKeccak256( - input.types, - this.parseArgs(input.values) - ); - } - - public soliditySha256(input: Query.Input_soliditySha256): string { - return ethers.utils.soliditySha256( - input.types, - this.parseArgs(input.values) - ); - } - - public async getSignerAddress( - input: Query.Input_getSignerAddress - ): Promise { - const connection = await this.getConnection(input.connection); - return await connection.getSigner().getAddress(); - } +export interface EthereumPluginConfigs + extends EthereumConfig, + Record {} - public async getSignerBalance( - input: Query.Input_getSignerBalance - ): Promise { - const connection = await this.getConnection(input.connection); - return ( - await connection.getSigner().getBalance(input.blockTag || undefined) - ).toString(); - } - - public async getSignerTransactionCount( - input: Query.Input_getSignerTransactionCount - ): Promise { - const connection = await this.getConnection(input.connection); - return ( - await connection - .getSigner() - .getTransactionCount(input.blockTag || undefined) - ).toString(); - } - - public async getGasPrice(input: Query.Input_getGasPrice): Promise { - const connection = await this.getConnection(input.connection); - return (await connection.getSigner().getGasPrice()).toString(); - } - - public async estimateTransactionGas( - input: Query.Input_estimateTransactionGas - ): Promise { - const connection = await this.getConnection(input.connection); - return ( - await connection.getSigner().estimateGas(Mapping.fromTxRequest(input.tx)) - ).toString(); - } - - public async estimateContractCallGas( - input: Query.Input_estimateContractCallGas - ): Promise { - const connection = await this.getConnection(input.connection); - const contract = connection.getContract(input.address, [input.method]); - const funcs = Object.keys(contract.interface.functions); - - const gasPrice: string | null | undefined = input.txOverrides?.gasPrice; - const gasLimit: string | null | undefined = input.txOverrides?.gasLimit; - const value: string | null | undefined = input.txOverrides?.value; - - const gas = await contract.estimateGas[funcs[0]]( - ...this.parseArgs(input.args), - { - gasPrice: gasPrice ? ethers.BigNumber.from(gasPrice) : undefined, - gasLimit: gasLimit ? ethers.BigNumber.from(gasLimit) : undefined, - value: value ? ethers.BigNumber.from(value) : undefined, - } - ); - - return gas.toString(); - } - - public checkAddress(input: Query.Input_checkAddress): boolean { - let address = input.address; - - try { - // If the address is all upper-case, convert to lower case - if (address.indexOf("0X") > -1) { - address = address.toLowerCase(); - } - - const result = ethers.utils.getAddress(address); - if (!result) { - return false; - } - - return true; - } catch (error) { - return false; - } - } - - public toWei(input: Query.Input_toWei): string { - const weiAmount = ethers.utils.parseEther(input.eth); - return weiAmount.toString(); - } - - public toEth(input: Query.Input_toEth): string { - const etherAmount = ethers.utils.formatEther(input.wei); - return etherAmount.toString(); - } - - public async waitForEvent( - input: Query.Input_waitForEvent - ): Promise { - const connection = await this.getConnection(input.connection); - const contract = connection.getContract(input.address, [input.event]); - const events = Object.keys(contract.interface.events); - const filter = contract.filters[events[0]](...this.parseArgs(input.args)); - - return Promise.race([ - new Promise((resolve) => { - contract.once( - filter, - (data: string, address: string, log: ethers.providers.Log) => { - resolve({ - data, - address, - log: Mapping.toLog(log), - } as Types.EventNotification); - } - ); - }), - new Promise((_, reject) => { - setTimeout(function () { - reject( - `Waiting for event "${input.event}" on contract "${input.address}" timed out` - ); - }, input.timeout || 60000); - }), - ]); - } - - public async awaitTransaction( - input: Query.Input_awaitTransaction - ): Promise { - const connection = await this.getConnection(input.connection); - const provider = connection.getProvider(); - - const res = await provider.waitForTransaction( - input.txHash, - input.confirmations, - input.timeout - ); - - return Mapping.toTxReceipt(res); - } - - /// Utils - - public async getConnection( - connection?: Types.Connection | null - ): Promise { - if (!connection) { - return this._connections[this._defaultNetwork]; - } - - const { networkNameOrChainId, node } = connection; - let result: Connection; - - // If a custom network is provided, either get an already - // established connection, or a create a new one - if (networkNameOrChainId) { - const networkStr = networkNameOrChainId.toLowerCase(); - if (this._connections[networkStr]) { - result = this._connections[networkStr]; - } else { - const chainId = Number.parseInt(networkStr); - - if (!isNaN(chainId)) { - result = Connection.fromNetwork(chainId); - } else { - result = Connection.fromNetwork(networkStr); - } - } - } else { - result = this._connections[this._defaultNetwork]; - } - - // If a custom node endpoint is provided, create a combined - // connection with the node's endpoint and a connection's signer - // (if one exists for the network) - if (node) { - const nodeConnection = Connection.fromNode(node); - const nodeNetwork = await nodeConnection.getProvider().getNetwork(); - - const establishedConnection = - this._connections[nodeNetwork.chainId.toString()] || - this._connections[nodeNetwork.name]; - - if (establishedConnection) { - try { - nodeConnection.setSigner(establishedConnection.getSigner()); - } catch (e) { - // It's okay if there isn't a signer available. - } - } - - result = nodeConnection; - } - - return result; - } - - public parseArgs(args?: string[] | null): unknown[] { - if (!args) { - return []; - } - - return args.map((arg: string) => - (arg.startsWith("[") && arg.endsWith("]")) || - (arg.startsWith("{") && arg.endsWith("}")) - ? JSON.parse(arg) - : arg - ); - } - - private async _callContractMethod( - input: Mutation.Input_callContractMethod - ): Promise { - const connection = await this.getConnection(input.connection); - const contract = connection.getContract(input.address, [input.method]); - const funcs = Object.keys(contract.interface.functions); - - const gasPrice: string | null | undefined = input.txOverrides?.gasPrice; - const gasLimit: string | null | undefined = input.txOverrides?.gasLimit; - const value: string | null | undefined = input.txOverrides?.value; - - return await contract[funcs[0]](...this.parseArgs(input.args), { - gasPrice: gasPrice ? ethers.BigNumber.from(gasPrice) : undefined, - gasLimit: gasLimit ? ethers.BigNumber.from(gasLimit) : undefined, - value: value ? ethers.BigNumber.from(value) : undefined, +export class EthereumPlugin extends Internal.EthereumPlugin { + constructor(config: EthereumPluginConfigs) { + super({ + query: config, + mutation: config, }); } } -export const ethereumPlugin: PluginFactory = ( - opts: EthereumConfig -) => { - return { - factory: () => new EthereumPlugin(opts), - manifest: manifest, - }; -}; +export const ethereumPlugin: PluginFactory = ( + opts: EthereumPluginConfigs +) => + Internal.ethereumPlugin({ + query: opts, + mutation: opts, + }); + export const plugin = ethereumPlugin; diff --git a/packages/js/plugins/ethereum/src/mutation/index.ts b/packages/js/plugins/ethereum/src/mutation/index.ts new file mode 100644 index 0000000000..3961e78a8a --- /dev/null +++ b/packages/js/plugins/ethereum/src/mutation/index.ts @@ -0,0 +1,144 @@ +import { + Client, + Module, + Input_callContractMethod, + Input_callContractMethodAndWait, + Input_sendTransaction, + Input_sendTransactionAndWait, + Input_deployContract, + Input_signMessage, + Input_sendRPC, + TxResponse, + TxReceipt, + Connection as SchemaConnection, +} from "./w3-man"; +import { EthereumConfig } from "../common/EthereumConfig"; +import { Connections, Connection, getConnection } from "../common/Connection"; +import * as Mapping from "../common/mapping"; +import { parseArgs } from "../common/parsing"; + +import { ethers } from "ethers"; + +export interface MutationConfig + extends EthereumConfig, + Record {} + +export class Mutation extends Module { + private _connections: Connections; + private _defaultNetwork: string; + + constructor(config: MutationConfig) { + super(config); + this._connections = Connection.fromConfigs(config.networks); + + // Assign the default network (mainnet if not provided) + if (config.defaultNetwork) { + this._defaultNetwork = config.defaultNetwork; + } else { + this._defaultNetwork = "mainnet"; + } + + // Create a connection for the default network if none exists + if (!this._connections[this._defaultNetwork]) { + this._connections[this._defaultNetwork] = Connection.fromNetwork( + this._defaultNetwork + ); + } + } + + public async callContractMethod( + input: Input_callContractMethod, + _client: Client + ): Promise { + const res = await this._callContractMethod(input); + return Mapping.toTxResponse(res); + } + + public async callContractMethodAndWait( + input: Input_callContractMethodAndWait, + _client: Client + ): Promise { + const response = await this._callContractMethod(input); + const res = await response.wait(); + return Mapping.toTxReceipt(res); + } + + public async sendTransaction( + input: Input_sendTransaction, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + const signer = connection.getSigner(); + const res = await signer.sendTransaction(Mapping.fromTxRequest(input.tx)); + return Mapping.toTxResponse(res); + } + + public async sendTransactionAndWait( + input: Input_sendTransactionAndWait, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + const signer = connection.getSigner(); + const response = await signer.sendTransaction( + Mapping.fromTxRequest(input.tx) + ); + const receipt = await response.wait(); + return Mapping.toTxReceipt(receipt); + } + + public async deployContract( + input: Input_deployContract, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + const signer = connection.getSigner(); + const factory = new ethers.ContractFactory( + input.abi, + input.bytecode, + signer + ); + const contract = await factory.deploy(...parseArgs(input.args)); + + await contract.deployTransaction.wait(); + return contract.address; + } + + public async signMessage( + input: Input_signMessage, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + return await connection.getSigner().signMessage(input.message); + } + + public async sendRPC(input: Input_sendRPC, _client: Client): Promise { + const connection = await this._getConnection(input.connection); + const provider = connection.getProvider(); + const response = await provider.send(input.method, input.params); + return response.toString(); + } + + private async _callContractMethod( + input: Input_callContractMethod + ): Promise { + const connection = await this._getConnection(input.connection); + const contract = connection.getContract(input.address, [input.method]); + const funcs = Object.keys(contract.interface.functions); + + const gasPrice: string | null | undefined = input.txOverrides?.gasPrice; + const gasLimit: string | null | undefined = input.txOverrides?.gasLimit; + const value: string | null | undefined = input.txOverrides?.value; + + return await contract[funcs[0]](...parseArgs(input.args), { + gasPrice: gasPrice ? ethers.BigNumber.from(gasPrice) : undefined, + gasLimit: gasLimit ? ethers.BigNumber.from(gasLimit) : undefined, + value: value ? ethers.BigNumber.from(value) : undefined, + }); + } + + private async _getConnection( + connection?: SchemaConnection | null + ): Promise { + return getConnection(this._connections, this._defaultNetwork, connection); + } +} diff --git a/packages/js/plugins/ethereum/src/mutation/schema.graphql b/packages/js/plugins/ethereum/src/mutation/schema.graphql new file mode 100644 index 0000000000..ff4c1893f3 --- /dev/null +++ b/packages/js/plugins/ethereum/src/mutation/schema.graphql @@ -0,0 +1,47 @@ +#import * from "../common/schema.graphql" + +type Mutation { + callContractMethod( + address: String! + method: String! + args: [String!] + connection: Connection + txOverrides: TxOverrides + ): TxResponse! + + callContractMethodAndWait( + address: String! + method: String! + args: [String!] + connection: Connection + txOverrides: TxOverrides + ): TxReceipt! + + sendTransaction( + tx: TxRequest! + connection: Connection + ): TxResponse! + + sendTransactionAndWait( + tx: TxRequest! + connection: Connection + ): TxReceipt! + + deployContract( + abi: String! + bytecode: String! + args: [String!] + connection: Connection + ): String! + + signMessage( + message: String! + connection: Connection + ): String! + + sendRPC( + method: String! + params: [String!]! + connection: Connection + ): String +} diff --git a/packages/js/plugins/ethereum/src/mutation/w3-man/index.ts b/packages/js/plugins/ethereum/src/mutation/w3-man/index.ts new file mode 100644 index 0000000000..6417838d60 --- /dev/null +++ b/packages/js/plugins/ethereum/src/mutation/w3-man/index.ts @@ -0,0 +1,4 @@ +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/core-js"; diff --git a/packages/js/plugins/ethereum/src/mutation/w3-man/module.ts b/packages/js/plugins/ethereum/src/mutation/w3-man/module.ts new file mode 100644 index 0000000000..3310e251ba --- /dev/null +++ b/packages/js/plugins/ethereum/src/mutation/w3-man/module.ts @@ -0,0 +1,94 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as Types from "./types"; + +import { Client, PluginModule, MaybeAsync } from "@web3api/core-js"; + +export interface Input_callContractMethod extends Record { + address: Types.String; + method: Types.String; + args?: Array | null; + connection?: Types.Connection | null; + txOverrides?: Types.TxOverrides | null; +} + +export interface Input_callContractMethodAndWait + extends Record { + address: Types.String; + method: Types.String; + args?: Array | null; + connection?: Types.Connection | null; + txOverrides?: Types.TxOverrides | null; +} + +export interface Input_sendTransaction extends Record { + tx: Types.TxRequest; + connection?: Types.Connection | null; +} + +export interface Input_sendTransactionAndWait extends Record { + tx: Types.TxRequest; + connection?: Types.Connection | null; +} + +export interface Input_deployContract extends Record { + abi: Types.String; + bytecode: Types.String; + args?: Array | null; + connection?: Types.Connection | null; +} + +export interface Input_signMessage extends Record { + message: Types.String; + connection?: Types.Connection | null; +} + +export interface Input_sendRPC extends Record { + method: Types.String; + params: Array; + connection?: Types.Connection | null; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule { + constructor(config: TConfig) { + super(config); + } + + abstract callContractMethod( + input: Input_callContractMethod, + client: Client + ): MaybeAsync; + + abstract callContractMethodAndWait( + input: Input_callContractMethodAndWait, + client: Client + ): MaybeAsync; + + abstract sendTransaction( + input: Input_sendTransaction, + client: Client + ): MaybeAsync; + + abstract sendTransactionAndWait( + input: Input_sendTransactionAndWait, + client: Client + ): MaybeAsync; + + abstract deployContract( + input: Input_deployContract, + client: Client + ): MaybeAsync; + + abstract signMessage( + input: Input_signMessage, + client: Client + ): MaybeAsync; + + abstract sendRPC( + input: Input_sendRPC, + client: Client + ): MaybeAsync; +} diff --git a/packages/js/plugins/ethereum/src/mutation/w3-man/types.ts b/packages/js/plugins/ethereum/src/mutation/w3-man/types.ts new file mode 100644 index 0000000000..24260bc972 --- /dev/null +++ b/packages/js/plugins/ethereum/src/mutation/w3-man/types.ts @@ -0,0 +1,119 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +// @ts-ignore +import * as Types from "./"; + +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; + +export interface TxReceipt { + to: string; + from: string; + contractAddress: string; + transactionIndex: UInt32; + root?: string | null; + gasUsed: BigInt; + logsBloom: string; + transactionHash: string; + logs: Array; + blockNumber: BigInt; + blockHash: string; + confirmations: UInt32; + cumulativeGasUsed: BigInt; + effectiveGasPrice: BigInt; + byzantium: boolean; + type: UInt32; + status?: UInt32 | null; +} + +export interface TxResponse { + hash: string; + to?: string | null; + from: string; + nonce: UInt32; + gasLimit: BigInt; + gasPrice?: BigInt | null; + data: string; + value: BigInt; + chainId: BigInt; + blockNumber?: BigInt | null; + blockHash?: string | null; + timestamp?: UInt32 | null; + confirmations: UInt32; + raw?: string | null; + r?: string | null; + s?: string | null; + v?: UInt32 | null; + type?: UInt32 | null; + accessList?: Array | null; +} + +export interface TxRequest { + to?: string | null; + from?: string | null; + nonce?: UInt32 | null; + gasLimit?: BigInt | null; + gasPrice?: BigInt | null; + data?: string | null; + value?: BigInt | null; + chainId?: BigInt | null; + type?: UInt32 | null; +} + +export interface TxOverrides { + gasLimit?: BigInt | null; + gasPrice?: BigInt | null; + value?: BigInt | null; +} + +export interface StaticTxResult { + result: string; + error: boolean; +} + +export interface Log { + blockNumber: BigInt; + blockHash: string; + transactionIndex: UInt32; + removed: boolean; + address: string; + data: string; + topics: Array; + transactionHash: string; + logIndex: UInt32; +} + +export interface EventNotification { + data: string; + address: string; + log: Types.Log; +} + +export interface Access { + address: string; + storageKeys: Array; +} + +export interface Connection { + node?: string | null; + networkNameOrChainId?: string | null; +} + +export interface Network { + name: string; + chainId: BigInt; + ensAddress?: string | null; +} diff --git a/packages/js/plugins/ethereum/src/query/index.ts b/packages/js/plugins/ethereum/src/query/index.ts new file mode 100644 index 0000000000..56e8e432a3 --- /dev/null +++ b/packages/js/plugins/ethereum/src/query/index.ts @@ -0,0 +1,323 @@ +import { + Client, + Module, + Input_callContractView, + Input_callContractStatic, + Input_getBalance, + Input_encodeParams, + Input_encodeFunction, + Input_solidityPack, + Input_solidityKeccak256, + Input_soliditySha256, + Input_getSignerAddress, + Input_getSignerBalance, + Input_getSignerTransactionCount, + Input_getGasPrice, + Input_estimateTransactionGas, + Input_estimateContractCallGas, + Input_checkAddress, + Input_toWei, + Input_toEth, + Input_waitForEvent, + Input_awaitTransaction, + Input_getNetwork, + BigInt, + StaticTxResult, + EventNotification, + TxReceipt, + Network, + Connection as SchemaConnection, +} from "./w3-man"; +import { EthereumConfig } from "../common/EthereumConfig"; +import { Connections, Connection, getConnection } from "../common/Connection"; +import * as Mapping from "../common/mapping"; +import { parseArgs } from "../common/parsing"; + +import { ethers } from "ethers"; +import { defaultAbiCoder } from "ethers/lib/utils"; + +export interface QueryConfig extends EthereumConfig, Record {} + +export class Query extends Module { + private _connections: Connections; + private _defaultNetwork: string; + + constructor(config: QueryConfig) { + super(config); + this._connections = Connection.fromConfigs(config.networks); + + // Assign the default network (mainnet if not provided) + if (config.defaultNetwork) { + this._defaultNetwork = config.defaultNetwork; + } else { + this._defaultNetwork = "mainnet"; + } + + // Create a connection for the default network if none exists + if (!this._connections[this._defaultNetwork]) { + this._connections[this._defaultNetwork] = Connection.fromNetwork( + this._defaultNetwork + ); + } + } + + async callContractView( + input: Input_callContractView, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + const contract = connection.getContract( + input.address, + [input.method], + false + ); + const funcs = Object.keys(contract.interface.functions); + const res = await contract[funcs[0]](...parseArgs(input.args)); + return res.toString(); + } + + async callContractStatic( + input: Input_callContractStatic, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + const contract = connection.getContract(input.address, [input.method]); + const funcs = Object.keys(contract.interface.functions); + + try { + const res = await contract.callStatic[funcs[0]]( + ...parseArgs(input.args), + { + gasPrice: input.gasPrice + ? ethers.BigNumber.from(input.gasPrice) + : undefined, + gasLimit: input.gasLimit + ? ethers.BigNumber.from(input.gasLimit) + : undefined, + value: input.value ? ethers.BigNumber.from(input.value) : undefined, + } + ); + return { + result: res.toString(), + error: false, + }; + } catch (e) { + return { + result: e.reason, + error: true, + }; + } + } + + async getBalance(input: Input_getBalance, _client: Client): Promise { + const connection = await this._getConnection(input.connection); + return ( + await connection + .getProvider() + .getBalance(input.address, input.blockTag || undefined) + ).toString(); + } + + async encodeParams( + input: Input_encodeParams, + _client: Client + ): Promise { + return defaultAbiCoder.encode(input.types, parseArgs(input.values)); + } + + async encodeFunction( + input: Input_encodeFunction, + _client: Client + ): Promise { + const functionInterface = ethers.Contract.getInterface([input.method]); + return functionInterface.encodeFunctionData( + functionInterface.functions[Object.keys(functionInterface.functions)[0]], + parseArgs(input.args) + ); + } + + async solidityPack( + input: Input_solidityPack, + _client: Client + ): Promise { + return ethers.utils.solidityPack(input.types, parseArgs(input.values)); + } + + async solidityKeccak256( + input: Input_solidityKeccak256, + _client: Client + ): Promise { + return ethers.utils.solidityKeccak256(input.types, parseArgs(input.values)); + } + + async soliditySha256( + input: Input_soliditySha256, + _client: Client + ): Promise { + return ethers.utils.soliditySha256(input.types, parseArgs(input.values)); + } + + async getSignerAddress( + input: Input_getSignerAddress, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + return await connection.getSigner().getAddress(); + } + + async getSignerBalance( + input: Input_getSignerBalance, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + return ( + await connection.getSigner().getBalance(input.blockTag || undefined) + ).toString(); + } + + async getSignerTransactionCount( + input: Input_getSignerTransactionCount, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + return ( + await connection + .getSigner() + .getTransactionCount(input.blockTag || undefined) + ).toString(); + } + + async getGasPrice( + input: Input_getGasPrice, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + return (await connection.getSigner().getGasPrice()).toString(); + } + + async estimateTransactionGas( + input: Input_estimateTransactionGas, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + return ( + await connection.getSigner().estimateGas(Mapping.fromTxRequest(input.tx)) + ).toString(); + } + + async estimateContractCallGas( + input: Input_estimateContractCallGas, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + const contract = connection.getContract(input.address, [input.method]); + const funcs = Object.keys(contract.interface.functions); + + const gasPrice: string | null | undefined = input.txOverrides?.gasPrice; + const gasLimit: string | null | undefined = input.txOverrides?.gasLimit; + const value: string | null | undefined = input.txOverrides?.value; + + const gas = await contract.estimateGas[funcs[0]](...parseArgs(input.args), { + gasPrice: gasPrice ? ethers.BigNumber.from(gasPrice) : undefined, + gasLimit: gasLimit ? ethers.BigNumber.from(gasLimit) : undefined, + value: value ? ethers.BigNumber.from(value) : undefined, + }); + + return gas.toString(); + } + + async checkAddress( + input: Input_checkAddress, + _client: Client + ): Promise { + let address = input.address; + + try { + // If the address is all upper-case, convert to lower case + if (address.indexOf("0X") > -1) { + address = address.toLowerCase(); + } + + const result = ethers.utils.getAddress(address); + if (!result) { + return false; + } + + return true; + } catch (error) { + return false; + } + } + + async toWei(input: Input_toWei, _client: Client): Promise { + const weiAmount = ethers.utils.parseEther(input.eth); + return weiAmount.toString(); + } + + async toEth(input: Input_toEth, _client: Client): Promise { + const etherAmount = ethers.utils.formatEther(input.wei); + return etherAmount.toString(); + } + + async waitForEvent( + input: Input_waitForEvent, + _client: Client + ): Promise { + const connection = await this._getConnection(input.connection); + const contract = connection.getContract(input.address, [input.event]); + const events = Object.keys(contract.interface.events); + const filter = contract.filters[events[0]](...parseArgs(input.args)); + + return Promise.race([ + new Promise((resolve) => { + contract.once( + filter, + (data: string, address: string, log: ethers.providers.Log) => { + resolve({ + data, + address, + log: Mapping.toLog(log), + } as EventNotification); + } + ); + }), + new Promise((_, reject) => { + setTimeout(function () { + reject( + `Waiting for event "${input.event}" on contract "${input.address}" timed out` + ); + }, input.timeout || 60000); + }), + ]); + } + + async awaitTransaction(input: Input_awaitTransaction): Promise { + const connection = await this._getConnection(input.connection); + const provider = connection.getProvider(); + + const res = await provider.waitForTransaction( + input.txHash, + input.confirmations, + input.timeout + ); + + return Mapping.toTxReceipt(res); + } + + async getNetwork(input: Input_getNetwork): Promise { + const connection = await this._getConnection(input.connection); + const provider = connection.getProvider(); + const network = await provider.getNetwork(); + return { + name: network.name, + chainId: network.chainId.toString(), + ensAddress: network.ensAddress, + }; + } + + private async _getConnection( + connection?: SchemaConnection | null + ): Promise { + return getConnection(this._connections, this._defaultNetwork, connection); + } +} diff --git a/packages/js/plugins/ethereum/src/query/schema.graphql b/packages/js/plugins/ethereum/src/query/schema.graphql new file mode 100644 index 0000000000..bcb363035a --- /dev/null +++ b/packages/js/plugins/ethereum/src/query/schema.graphql @@ -0,0 +1,105 @@ +#import * from "../common/schema.graphql" + +type Query { + callContractView( + address: String! + method: String! + args: [String!] + connection: Connection + ): String! + + callContractStatic( + address: String! + method: String! + args: [String!] + connection: Connection + txOverrides: TxOverrides + ): StaticTxResult! + + getBalance( + address: String! + blockTag: BigInt + connection: 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: Connection + ): String! + + getSignerBalance( + blockTag: BigInt + connection: Connection + ): BigInt! + + getSignerTransactionCount( + blockTag: BigInt + connection: Connection + ): BigInt! + + getGasPrice( + connection: Connection + ): BigInt! + + estimateTransactionGas( + tx: TxRequest! + connection: Connection + ): BigInt! + + estimateContractCallGas( + address: String! + method: String! + args: [String!] + connection: Connection + txOverrides: TxOverrides + ): BigInt! + + checkAddress( + address: String! + ): Boolean! + + toWei(eth: String!): BigInt! + + toEth(wei: BigInt!): String! + + awaitTransaction( + txHash: String! + confirmations: UInt32! + timeout: UInt32! + connection: Connection + ): TxReceipt! + + waitForEvent( + address: String! + event: String! + args: [String!] + timeout: UInt32 + connection: Connection + ): EventNotification! + + getNetwork(connection: Connection): Network! +} diff --git a/packages/js/plugins/ethereum/src/query/w3-man/index.ts b/packages/js/plugins/ethereum/src/query/w3-man/index.ts new file mode 100644 index 0000000000..6417838d60 --- /dev/null +++ b/packages/js/plugins/ethereum/src/query/w3-man/index.ts @@ -0,0 +1,4 @@ +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/core-js"; diff --git a/packages/js/plugins/ethereum/src/query/w3-man/module.ts b/packages/js/plugins/ethereum/src/query/w3-man/module.ts new file mode 100644 index 0000000000..aad7bb3eb9 --- /dev/null +++ b/packages/js/plugins/ethereum/src/query/w3-man/module.ts @@ -0,0 +1,217 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as Types from "./types"; + +import { Client, PluginModule, MaybeAsync } from "@web3api/core-js"; + +export interface Input_callContractView extends Record { + address: Types.String; + method: Types.String; + args?: Array | null; + connection?: Types.Connection | null; +} + +export interface Input_callContractStatic extends Record { + address: Types.String; + method: Types.String; + args?: Array | null; + connection?: Types.Connection | null; + txOverrides?: Types.TxOverrides | null; +} + +export interface Input_getBalance extends Record { + address: Types.String; + blockTag?: Types.BigInt; + connection?: Types.Connection; +} + +export interface Input_encodeParams extends Record { + types: Array; + values: Array; +} + +export interface Input_encodeFunction extends Record { + method: Types.String; + args?: Array | null; +} + +export interface Input_solidityPack extends Record { + types: Array; + values: Array; +} + +export interface Input_solidityKeccak256 extends Record { + types: Array; + values: Array; +} + +export interface Input_soliditySha256 extends Record { + types: Array; + values: Array; +} + +export interface Input_getSignerAddress extends Record { + connection?: Types.Connection | null; +} + +export interface Input_getSignerBalance extends Record { + blockTag?: Types.BigInt | null; + connection?: Types.Connection | null; +} + +export interface Input_getSignerTransactionCount + extends Record { + blockTag?: Types.BigInt | null; + connection?: Types.Connection | null; +} + +export interface Input_getGasPrice extends Record { + connection?: Types.Connection | null; +} + +export interface Input_estimateTransactionGas extends Record { + tx: Types.TxRequest; + connection?: Types.Connection | null; +} + +export interface Input_estimateContractCallGas extends Record { + address: Types.String; + method: Types.String; + args?: Array | null; + connection?: Types.Connection | null; + txOverrides?: Types.TxOverrides | null; +} + +export interface Input_checkAddress extends Record { + address: Types.String; +} + +export interface Input_toWei extends Record { + eth: Types.String; +} + +export interface Input_toEth extends Record { + wei: Types.BigInt; +} + +export interface Input_awaitTransaction extends Record { + txHash: Types.String; + confirmations: Types.UInt32; + timeout: Types.UInt32; + connection?: Types.Connection | null; +} + +export interface Input_waitForEvent extends Record { + address: Types.String; + event: Types.String; + args?: Array | null; + timeout?: Types.UInt32 | null; + connection?: Types.Connection | null; +} + +export interface Input_getNetwork extends Record { + connection?: Types.Connection | null; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule { + constructor(config: TConfig) { + super(config); + } + + abstract callContractView( + input: Input_callContractView, + client: Client + ): MaybeAsync; + + abstract callContractStatic( + input: Input_callContractStatic, + client: Client + ): MaybeAsync; + + abstract getBalance( + input: Input_getBalance, + client: Client + ): MaybeAsync; + + abstract encodeParams( + input: Input_encodeParams, + client: Client + ): MaybeAsync; + + abstract encodeFunction( + input: Input_encodeFunction, + client: Client + ): MaybeAsync; + + abstract solidityPack( + input: Input_solidityPack, + client: Client + ): MaybeAsync; + + abstract solidityKeccak256( + input: Input_solidityKeccak256, + client: Client + ): MaybeAsync; + + abstract soliditySha256( + input: Input_soliditySha256, + client: Client + ): MaybeAsync; + + abstract getSignerAddress( + input: Input_getSignerAddress, + client: Client + ): MaybeAsync; + + abstract getSignerBalance( + input: Input_getSignerBalance, + client: Client + ): MaybeAsync; + + abstract getSignerTransactionCount( + input: Input_getSignerTransactionCount, + client: Client + ): MaybeAsync; + + abstract getGasPrice( + input: Input_getGasPrice, + client: Client + ): MaybeAsync; + + abstract estimateTransactionGas( + input: Input_estimateTransactionGas, + client: Client + ): MaybeAsync; + + abstract estimateContractCallGas( + input: Input_estimateContractCallGas, + client: Client + ): MaybeAsync; + + abstract checkAddress( + input: Input_checkAddress, + client: Client + ): MaybeAsync; + + abstract toWei(input: Input_toWei, client: Client): MaybeAsync; + + abstract toEth(input: Input_toEth, client: Client): MaybeAsync; + + abstract awaitTransaction( + input: Input_awaitTransaction, + client: Client + ): MaybeAsync; + + abstract waitForEvent( + input: Input_waitForEvent, + client: Client + ): MaybeAsync; + + abstract getNetwork( + input: Input_getNetwork, + client: Client + ): MaybeAsync; +} diff --git a/packages/js/plugins/ethereum/src/query/w3-man/types.ts b/packages/js/plugins/ethereum/src/query/w3-man/types.ts new file mode 100644 index 0000000000..24260bc972 --- /dev/null +++ b/packages/js/plugins/ethereum/src/query/w3-man/types.ts @@ -0,0 +1,119 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +// @ts-ignore +import * as Types from "./"; + +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; + +export interface TxReceipt { + to: string; + from: string; + contractAddress: string; + transactionIndex: UInt32; + root?: string | null; + gasUsed: BigInt; + logsBloom: string; + transactionHash: string; + logs: Array; + blockNumber: BigInt; + blockHash: string; + confirmations: UInt32; + cumulativeGasUsed: BigInt; + effectiveGasPrice: BigInt; + byzantium: boolean; + type: UInt32; + status?: UInt32 | null; +} + +export interface TxResponse { + hash: string; + to?: string | null; + from: string; + nonce: UInt32; + gasLimit: BigInt; + gasPrice?: BigInt | null; + data: string; + value: BigInt; + chainId: BigInt; + blockNumber?: BigInt | null; + blockHash?: string | null; + timestamp?: UInt32 | null; + confirmations: UInt32; + raw?: string | null; + r?: string | null; + s?: string | null; + v?: UInt32 | null; + type?: UInt32 | null; + accessList?: Array | null; +} + +export interface TxRequest { + to?: string | null; + from?: string | null; + nonce?: UInt32 | null; + gasLimit?: BigInt | null; + gasPrice?: BigInt | null; + data?: string | null; + value?: BigInt | null; + chainId?: BigInt | null; + type?: UInt32 | null; +} + +export interface TxOverrides { + gasLimit?: BigInt | null; + gasPrice?: BigInt | null; + value?: BigInt | null; +} + +export interface StaticTxResult { + result: string; + error: boolean; +} + +export interface Log { + blockNumber: BigInt; + blockHash: string; + transactionIndex: UInt32; + removed: boolean; + address: string; + data: string; + topics: Array; + transactionHash: string; + logIndex: UInt32; +} + +export interface EventNotification { + data: string; + address: string; + log: Types.Log; +} + +export interface Access { + address: string; + storageKeys: Array; +} + +export interface Connection { + node?: string | null; + networkNameOrChainId?: string | null; +} + +export interface Network { + name: string; + chainId: BigInt; + ensAddress?: string | null; +} diff --git a/packages/js/plugins/ethereum/src/resolvers.ts b/packages/js/plugins/ethereum/src/resolvers.ts deleted file mode 100644 index c23046a7c1..0000000000 --- a/packages/js/plugins/ethereum/src/resolvers.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { EthereumPlugin as Plugin } from "."; -import { Query, Mutation } from "./w3"; -import * as Types from "./w3"; - -export const mutation = (plugin: Plugin): Mutation.Module => ({ - callContractMethod: async ( - input: Mutation.Input_callContractMethod - ): Promise => { - return plugin.callContractMethod(input); - }, - - callContractMethodAndWait: async ( - input: Mutation.Input_callContractMethodAndWait - ): Promise => { - return plugin.callContractMethodAndWait(input); - }, - - sendTransaction: async ( - input: Mutation.Input_sendTransaction - ): Promise => { - return plugin.sendTransaction(input); - }, - - sendTransactionAndWait: async ( - input: Mutation.Input_sendTransactionAndWait - ): Promise => { - return plugin.sendTransactionAndWait(input); - }, - - deployContract: async ( - input: Mutation.Input_deployContract - ): Promise => { - return plugin.deployContract(input); - }, - - signMessage: async (input: Mutation.Input_signMessage): Promise => { - return plugin.signMessage(input); - }, - - sendRPC: async (input: Mutation.Input_sendRPC): Promise => { - return plugin.sendRPC(input); - }, -}); - -export const query = (plugin: Plugin): Query.Module => ({ - callContractView: async ( - input: Query.Input_callContractView - ): Promise => { - return plugin.callContractView(input); - }, - - callContractStatic: async ( - input: Query.Input_callContractStatic - ): Promise => { - return plugin.callContractStatic(input); - }, - - getBalance: async (input: Query.Input_getBalance): Promise => { - return plugin.getBalance(input); - }, - - encodeParams: async (input: Query.Input_encodeParams): Promise => { - return plugin.encodeParams(input); - }, - - encodeFunction: async ( - input: Query.Input_encodeFunction - ): Promise => { - return plugin.encodeFunction(input); - }, - - solidityPack: async (input: Query.Input_solidityPack): Promise => { - return plugin.solidityPack(input); - }, - - solidityKeccak256: async ( - input: Query.Input_solidityKeccak256 - ): Promise => { - return plugin.solidityKeccak256(input); - }, - - soliditySha256: async ( - input: Query.Input_soliditySha256 - ): Promise => { - return plugin.soliditySha256(input); - }, - - getSignerAddress: async ( - input: Query.Input_getSignerAddress - ): Promise => { - return plugin.getSignerAddress(input); - }, - - getSignerBalance: async ( - input: Query.Input_getSignerBalance - ): Promise => { - return plugin.getSignerBalance(input); - }, - - getSignerTransactionCount: async ( - input: Query.Input_getSignerTransactionCount - ): Promise => { - return plugin.getSignerTransactionCount(input); - }, - - getGasPrice: async (input: Query.Input_getGasPrice): Promise => { - return plugin.getGasPrice(input); - }, - - estimateTransactionGas: async ( - input: Query.Input_estimateTransactionGas - ): Promise => { - return plugin.estimateTransactionGas(input); - }, - - estimateContractCallGas: async ( - input: Query.Input_estimateContractCallGas - ): Promise => { - return plugin.estimateContractCallGas(input); - }, - - checkAddress: async (input: Query.Input_checkAddress): Promise => { - return plugin.checkAddress(input); - }, - - toWei: async (input: Query.Input_toWei): Promise => { - return plugin.toWei(input); - }, - - toEth: async (input: Query.Input_toEth): Promise => { - return plugin.toEth(input); - }, - - waitForEvent: async ( - input: Query.Input_waitForEvent - ): Promise => { - return plugin.waitForEvent(input); - }, - - awaitTransaction: async ( - input: Query.Input_awaitTransaction - ): Promise => { - return plugin.awaitTransaction(input); - }, - - getNetwork: async (input: Query.Input_getNetwork): Promise => { - return plugin.getNetwork(input); - }, -}); diff --git a/packages/js/plugins/ethereum/src/w3-man/index.ts b/packages/js/plugins/ethereum/src/w3-man/index.ts new file mode 100644 index 0000000000..b4849fdac4 --- /dev/null +++ b/packages/js/plugins/ethereum/src/w3-man/index.ts @@ -0,0 +1,3 @@ +export * from "./schema"; +export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/js/plugins/ethereum/src/w3-man/manifest.ts b/packages/js/plugins/ethereum/src/w3-man/manifest.ts new file mode 100644 index 0000000000..41ca650b30 --- /dev/null +++ b/packages/js/plugins/ethereum/src/w3-man/manifest.ts @@ -0,0 +1,13 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +/* eslint-disable @typescript-eslint/no-unused-vars */ + +import { schema } from "./"; + +import { PluginPackageManifest } from "@web3api/core-js"; + +export const manifest: PluginPackageManifest = { + schema, + implements: [], +}; diff --git a/packages/js/plugins/ethereum/src/w3-man/plugin.ts b/packages/js/plugins/ethereum/src/w3-man/plugin.ts new file mode 100644 index 0000000000..d111985ae7 --- /dev/null +++ b/packages/js/plugins/ethereum/src/w3-man/plugin.ts @@ -0,0 +1,44 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { Query, QueryConfig } from "../query"; +import { Mutation, MutationConfig } from "../mutation"; +import { manifest } from "./manifest"; + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; + +export interface EthereumPluginConfigs { + query: QueryConfig; + mutation: MutationConfig; +} + +export class EthereumPlugin implements Plugin { + constructor(private _configs: EthereumPluginConfigs) {} + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + query: new Query(this._configs.query), + mutation: new Mutation(this._configs.mutation), + }; + } +} + +export const ethereumPlugin: PluginFactory = ( + opts: EthereumPluginConfigs +) => { + return { + factory: () => new EthereumPlugin(opts), + manifest: manifest, + }; +}; + +export const plugin = ethereumPlugin; diff --git a/packages/js/plugins/ethereum/schema.graphql b/packages/js/plugins/ethereum/src/w3-man/schema.ts similarity index 81% rename from packages/js/plugins/ethereum/schema.graphql rename to packages/js/plugins/ethereum/src/w3-man/schema.ts index a72294586c..f339fa60cb 100644 --- a/packages/js/plugins/ethereum/schema.graphql +++ b/packages/js/plugins/ethereum/src/w3-man/schema.ts @@ -1,101 +1,41 @@ -type TxReceipt { - to: String! - from: String! - contractAddress: String! - transactionIndex: UInt32! - root: String - gasUsed: BigInt! - logsBloom: String! - transactionHash: String! - logs: [Log!]! - blockNumber: BigInt! - blockHash: String! - confirmations: UInt32! - cumulativeGasUsed: BigInt! - effectiveGasPrice: BigInt! - byzantium: Boolean! - type: UInt32! - status: UInt32 -} - -type 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: [Access!] -} - -type TxRequest { - to: String - from: String - nonce: UInt32 - gasLimit: BigInt - gasPrice: BigInt - data: String - value: BigInt - chainId: BigInt - type: UInt32 -} - -type TxOverrides { - gasLimit: BigInt - gasPrice: BigInt - value: BigInt -} - -type StaticTxResult { - result: String! - error: Boolean! -} - -type Log { - blockNumber: BigInt! - blockHash: String! - transactionIndex: UInt32! - removed: Boolean! - address: String! - data: String! - topics: [String!]! - transactionHash: String! - logIndex: UInt32! -} - -type EventNotification { - data: String! - address: String! - log: Log! -} - -type Access { - address: String! - storageKeys: [String!]! -} - -type Connection { - node: String - networkNameOrChainId: String -} - -type Network { - name: String! - chainId: BigInt! - ensAddress: String -} +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export const schema = `### 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 { callContractView( @@ -179,9 +119,13 @@ type Query { address: String! ): Boolean! - toWei(eth: String!): BigInt! + toWei( + eth: String! + ): BigInt! - toEth(wei: BigInt!): String! + toEth( + wei: BigInt! + ): String! awaitTransaction( txHash: String! @@ -198,7 +142,9 @@ type Query { connection: Connection ): EventNotification! - getNetwork(connection: Connection): Network! + getNetwork( + connection: Connection + ): Network! } type Mutation { @@ -246,3 +192,111 @@ type Mutation { connection: Connection ): String } + +type TxReceipt { + to: String! + from: String! + contractAddress: String! + transactionIndex: UInt32! + root: String + gasUsed: BigInt! + logsBloom: String! + transactionHash: String! + logs: [Log!]! + blockNumber: BigInt! + blockHash: String! + confirmations: UInt32! + cumulativeGasUsed: BigInt! + effectiveGasPrice: BigInt! + byzantium: Boolean! + type: UInt32! + status: UInt32 +} + +type 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: [Access!] +} + +type TxRequest { + to: String + from: String + nonce: UInt32 + gasLimit: BigInt + gasPrice: BigInt + data: String + value: BigInt + chainId: BigInt + type: UInt32 +} + +type TxOverrides { + gasLimit: BigInt + gasPrice: BigInt + value: BigInt +} + +type StaticTxResult { + result: String! + error: Boolean! +} + +type Log { + blockNumber: BigInt! + blockHash: String! + transactionIndex: UInt32! + removed: Boolean! + address: String! + data: String! + topics: [String!]! + transactionHash: String! + logIndex: UInt32! +} + +type EventNotification { + data: String! + address: String! + log: Log! +} + +type Access { + address: String! + storageKeys: [String!]! +} + +type Connection { + node: String + networkNameOrChainId: String +} + +type Network { + name: String! + chainId: BigInt! + ensAddress: String +} + +### Imported Queries START ### + +### Imported Queries END ### + +### Imported Objects START ### + +### Imported Objects END ### +`; diff --git a/packages/js/plugins/ethereum/web3api.plugin.yaml b/packages/js/plugins/ethereum/web3api.plugin.yaml index b21359a846..ebe45fee11 100644 --- a/packages/js/plugins/ethereum/web3api.plugin.yaml +++ b/packages/js/plugins/ethereum/web3api.plugin.yaml @@ -1,3 +1,10 @@ -format: 0.0.1-prealpha.1 +format: 0.0.1-prealpha.2 language: plugin/typescript -schema: ./schema.graphql +name: Ethereum +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts diff --git a/packages/js/plugins/filesystem/package.json b/packages/js/plugins/filesystem/package.json index 5f8e20a358..3552119925 100644 --- a/packages/js/plugins/filesystem/package.json +++ b/packages/js/plugins/filesystem/package.json @@ -9,11 +9,12 @@ }, "main": "build/index.js", "files": [ - "build", - "schema.graphql" + "build" ], "scripts": { - "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "build": "rimraf ./build ./**/w3 ./*/**/w3 && tsc --project tsconfig.build.json", + "build:migrate": "npx w3 plugin codegen", + "build:bak": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", "codegen": "node ../../../../dependencies/node_modules/@web3api/cli/bin/w3 plugin codegen", "lint": "eslint --color -c ../../../../.eslintrc.js src/", "test": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts b/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts index 9b34f02fa0..b072d7cf43 100644 --- a/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts +++ b/packages/js/plugins/filesystem/src/__tests__/e2e.spec.ts @@ -32,7 +32,7 @@ describe("Filesystem plugin", () => { plugins: [ { uri: "w3://ens/fs.web3api.eth", - plugin: filesystemPlugin(), + plugin: filesystemPlugin({ query: {} }), }, // IPFS is required for downloading Web3API packages { @@ -46,9 +46,11 @@ describe("Filesystem plugin", () => { { uri: "w3://ens/ens.web3api.eth", plugin: ensPlugin({ - addresses: { - testnet: ens, - }, + query: { + addresses: { + testnet: ens, + }, + } }), }, { diff --git a/packages/js/plugins/filesystem/src/index.ts b/packages/js/plugins/filesystem/src/index.ts index d80dc0a00a..a7af0fac7a 100644 --- a/packages/js/plugins/filesystem/src/index.ts +++ b/packages/js/plugins/filesystem/src/index.ts @@ -1,24 +1,3 @@ -import { query } from "./resolvers"; -import { manifest, Query } from "./w3"; +// TIP: All user-defined code lives in the module folders (./query, ./mutation) -import { Plugin, PluginPackage, PluginPackageManifest } from "@web3api/core-js"; - -export class FilesystemPlugin extends Plugin { - public static manifest(): PluginPackageManifest { - return manifest; - } - - public getModules(): { query: Query.Module } { - return { - query: query(), - }; - } -} - -export const filesystemPlugin = (): PluginPackage => { - return { - factory: () => new FilesystemPlugin(), - manifest: manifest, - }; -}; -export const plugin = filesystemPlugin; +export * from "./w3-man"; diff --git a/packages/js/plugins/filesystem/src/resolvers.ts b/packages/js/plugins/filesystem/src/query/index.ts similarity index 65% rename from packages/js/plugins/filesystem/src/resolvers.ts rename to packages/js/plugins/filesystem/src/query/index.ts index 5ea4d0978d..560d83404d 100644 --- a/packages/js/plugins/filesystem/src/resolvers.ts +++ b/packages/js/plugins/filesystem/src/query/index.ts @@ -1,11 +1,22 @@ -import { Query } from "./w3"; +import { + Client, + Module, + Input_tryResolveUri, + Input_getFile, + UriResolver_MaybeUriOrManifest, + Bytes, +} from "./w3-man"; import path from "path"; import fs from "fs"; -export const query = (): Query.Module => ({ - // uri-resolver.core.web3api.eth - tryResolveUri: async (input: Query.Input_tryResolveUri) => { +export type QueryConfig = Record; + +export class Query extends Module { + async tryResolveUri( + input: Input_tryResolveUri, + _client: Client + ): Promise { if (input.authority !== "fs") { return null; } @@ -36,12 +47,13 @@ export const query = (): Query.Module => ({ // Noting found return { uri: null, manifest: null }; } - }, - getFile: async (_input: Query.Input_getFile) => { + } + + async getFile(_input: Input_getFile, _client: Client): Promise { try { return await fs.promises.readFile(_input.path); } catch (e) { return null; } - }, -}); + } +} diff --git a/packages/js/plugins/filesystem/schema.graphql b/packages/js/plugins/filesystem/src/query/schema.graphql similarity index 100% rename from packages/js/plugins/filesystem/schema.graphql rename to packages/js/plugins/filesystem/src/query/schema.graphql diff --git a/packages/js/plugins/filesystem/src/query/w3-man/index.ts b/packages/js/plugins/filesystem/src/query/w3-man/index.ts new file mode 100644 index 0000000000..6417838d60 --- /dev/null +++ b/packages/js/plugins/filesystem/src/query/w3-man/index.ts @@ -0,0 +1,4 @@ +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/core-js"; diff --git a/packages/js/plugins/filesystem/src/query/w3-man/module.ts b/packages/js/plugins/filesystem/src/query/w3-man/module.ts new file mode 100644 index 0000000000..08d098fa52 --- /dev/null +++ b/packages/js/plugins/filesystem/src/query/w3-man/module.ts @@ -0,0 +1,33 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as Types from "./types"; + +import { Client, PluginModule, MaybeAsync } from "@web3api/core-js"; + +export interface Input_tryResolveUri extends Record { + authority: Types.String; + path: Types.String; +} + +export interface Input_getFile extends Record { + path: Types.String; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule { + constructor(config: TConfig) { + super(config); + } + + abstract tryResolveUri( + input: Input_tryResolveUri, + client: Client + ): MaybeAsync; + + abstract getFile( + input: Input_getFile, + client: Client + ): MaybeAsync; +} diff --git a/packages/js/plugins/filesystem/src/query/w3-man/types.ts b/packages/js/plugins/filesystem/src/query/w3-man/types.ts new file mode 100644 index 0000000000..486a91a90d --- /dev/null +++ b/packages/js/plugins/filesystem/src/query/w3-man/types.ts @@ -0,0 +1,76 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +// @ts-ignore +import * as Types from "./"; + +// @ts-ignore +import { Client, InvokeApiResult } from "@web3api/core-js"; + +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; + +/// Imported Objects START /// + +/* URI: "ens/uri-resolver.core.web3api.eth" */ +export interface UriResolver_MaybeUriOrManifest { + uri?: string | null; + manifest?: string | null; +} + +/// Imported Objects END /// + +/// Imported Queries START /// + +/* URI: "ens/uri-resolver.core.web3api.eth" */ +interface UriResolver_Query_Input_tryResolveUri + extends Record { + authority: string; + path: string; +} + +/* URI: "ens/uri-resolver.core.web3api.eth" */ +interface UriResolver_Query_Input_getFile extends Record { + path: string; +} + +/* URI: "ens/uri-resolver.core.web3api.eth" */ +export const UriResolver_Query = { + tryResolveUri: async ( + input: UriResolver_Query_Input_tryResolveUri, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/uri-resolver.core.web3api.eth", + module: "query", + method: "tryResolveUri", + input, + }); + }, + + getFile: async ( + input: UriResolver_Query_Input_getFile, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/uri-resolver.core.web3api.eth", + module: "query", + method: "getFile", + input, + }); + }, +}; + +/// Imported Queries END /// diff --git a/packages/js/plugins/filesystem/src/w3-man/index.ts b/packages/js/plugins/filesystem/src/w3-man/index.ts new file mode 100644 index 0000000000..b4849fdac4 --- /dev/null +++ b/packages/js/plugins/filesystem/src/w3-man/index.ts @@ -0,0 +1,3 @@ +export * from "./schema"; +export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/js/plugins/filesystem/src/w3-man/manifest.ts b/packages/js/plugins/filesystem/src/w3-man/manifest.ts new file mode 100644 index 0000000000..278a2d0d7f --- /dev/null +++ b/packages/js/plugins/filesystem/src/w3-man/manifest.ts @@ -0,0 +1,15 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +import { schema } from "./"; + +// @ts-ignore +import { PluginPackageManifest, Uri } from "@web3api/core-js"; + +export const manifest: PluginPackageManifest = { + schema, + implements: [new Uri("ens/uri-resolver.core.web3api.eth")], +}; diff --git a/packages/js/plugins/filesystem/src/w3-man/plugin.ts b/packages/js/plugins/filesystem/src/w3-man/plugin.ts new file mode 100644 index 0000000000..8c3f0c40a8 --- /dev/null +++ b/packages/js/plugins/filesystem/src/w3-man/plugin.ts @@ -0,0 +1,41 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { Query, QueryConfig } from "../query"; +import { manifest } from "./manifest"; + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; + +export interface FilesystemPluginConfigs { + query: QueryConfig; +} + +export class FilesystemPlugin implements Plugin { + constructor(private _configs: FilesystemPluginConfigs) {} + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + query: new Query(this._configs.query), + }; + } +} + +export const filesystemPlugin: PluginFactory = ( + opts: FilesystemPluginConfigs +) => { + return { + factory: () => new FilesystemPlugin(opts), + manifest: manifest, + }; +}; + +export const plugin = filesystemPlugin; diff --git a/packages/js/plugins/filesystem/src/w3-man/schema.ts b/packages/js/plugins/filesystem/src/w3-man/schema.ts new file mode 100644 index 0000000000..ebba9e7751 --- /dev/null +++ b/packages/js/plugins/filesystem/src/w3-man/schema.ts @@ -0,0 +1,87 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export const schema = `### 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 implements UriResolver_Query @imports( + types: [ + "UriResolver_Query", + "UriResolver_MaybeUriOrManifest" + ] +) { + tryResolveUri( + authority: String! + path: String! + ): UriResolver_MaybeUriOrManifest + + getFile( + path: String! + ): Bytes +} + +### Imported Queries START ### + +type UriResolver_Query @imported( + uri: "ens/uri-resolver.core.web3api.eth", + namespace: "UriResolver", + nativeType: "Query" +) { + tryResolveUri( + authority: String! + path: String! + ): UriResolver_MaybeUriOrManifest + + getFile( + path: String! + ): Bytes +} + +### Imported Queries END ### + +### Imported Objects START ### + +type UriResolver_MaybeUriOrManifest @imported( + uri: "ens/uri-resolver.core.web3api.eth", + namespace: "UriResolver", + nativeType: "MaybeUriOrManifest" +) { + uri: String + manifest: String +} + +### Imported Objects END ### +`; diff --git a/packages/js/plugins/filesystem/web3api.plugin.yaml b/packages/js/plugins/filesystem/web3api.plugin.yaml index fdc1da92f3..4bad3eb567 100644 --- a/packages/js/plugins/filesystem/web3api.plugin.yaml +++ b/packages/js/plugins/filesystem/web3api.plugin.yaml @@ -1,6 +1,10 @@ -format: 0.0.1-prealpha.1 +format: 0.0.1-prealpha.2 language: plugin/typescript -schema: ./schema.graphql +name: Filesystem +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts import_redirects: - uri: "ens/uri-resolver.core.web3api.eth" schema: ../../../core-interfaces/uri-resolver/src/query.graphql diff --git a/packages/js/plugins/graph-node/package.json b/packages/js/plugins/graph-node/package.json index 72681a01bf..83588fd1bc 100644 --- a/packages/js/plugins/graph-node/package.json +++ b/packages/js/plugins/graph-node/package.json @@ -9,11 +9,12 @@ }, "main": "build/index.js", "files": [ - "build", - "schema.graphql" + "build" ], "scripts": { - "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "build": "rimraf ./build ./**/w3 ./*/**/w3 && tsc --project tsconfig.build.json", + "build:migrate": "npx w3 plugin codegen", + "build:bak": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", "codegen": "node ../../../../dependencies/node_modules/@web3api/cli/bin/w3 plugin codegen", "lint": "eslint --color -c ../../../../.eslintrc.js src/", "test": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/graph-node/src/__tests__/e2e.spec.ts b/packages/js/plugins/graph-node/src/__tests__/e2e.spec.ts index 1d0dc92bd4..13acc36187 100644 --- a/packages/js/plugins/graph-node/src/__tests__/e2e.spec.ts +++ b/packages/js/plugins/graph-node/src/__tests__/e2e.spec.ts @@ -1,4 +1,5 @@ -import { plugin, GraphNodePlugin } from ".."; +import { plugin } from ".."; +import { Query } from "../query"; import { Web3ApiClient } from "@web3api/client-js"; const uri = "ens/graph-node.web3api.eth"; @@ -11,12 +12,14 @@ describe("Graph Node Plugin", () => { plugins: [{ uri, plugin: plugin({ - provider + query: { + provider + } }) }] }); - const graphNode = new GraphNodePlugin({ + const graphNode = new Query({ provider }); @@ -63,10 +66,10 @@ describe("Graph Node Plugin", () => { it("Throws if errors in querystring", async () => { await expect( - graphNode.query( - "ensdomains", - "ens", - `{ + graphNode.querySubgraph({ + subgraphAuthor: "ensdomains", + subgraphName: "ens", + query: `{ domains(first: 5) { ids names @@ -82,15 +85,14 @@ describe("Graph Node Plugin", () => { transactionID } }`, - client - ) + }, client) ).rejects.toThrowError(); try { - await graphNode.query( - "ensdomains", - "ens", - `{ + await graphNode.querySubgraph({ + subgraphAuthor: "ensdomains", + subgraphName: "ens", + query: `{ domains(first: 5) { ids names @@ -106,8 +108,7 @@ describe("Graph Node Plugin", () => { transactionID } }`, - client - ); + }, client); } catch (e) { expect(e.message).toContain( `Message: Type \`Domain\` has no field \`ids\`` @@ -123,10 +124,10 @@ describe("Graph Node Plugin", () => { it("Throws if wrong subgraph name/author", async () => { await expect( - graphNode.query( - "ens", - "ens", - `{ + graphNode.querySubgraph({ + subgraphAuthor: "ens", + subgraphName: "ens", + query: `{ domains(first: 5) { id name @@ -142,8 +143,7 @@ describe("Graph Node Plugin", () => { transactionID } }`, - client - ) + }, client) ).rejects.toThrowError( new RegExp( "Store error: query execution failed: Subgraph `ens/ens` not found", @@ -152,10 +152,10 @@ describe("Graph Node Plugin", () => { ); await expect( - graphNode.query( - "ensdomains", - "foo", - `{ + graphNode.querySubgraph({ + subgraphAuthor: "ensdomains", + subgraphName: "foo", + query: `{ domains(first: 5) { id name @@ -171,8 +171,7 @@ describe("Graph Node Plugin", () => { transactionID } }`, - client - ) + }, client) ).rejects.toThrowError( new RegExp( "Store error: query execution failed: Subgraph `ensdomains/foo` not found", diff --git a/packages/js/plugins/graph-node/src/index.ts b/packages/js/plugins/graph-node/src/index.ts index 46a3d66242..a7af0fac7a 100644 --- a/packages/js/plugins/graph-node/src/index.ts +++ b/packages/js/plugins/graph-node/src/index.ts @@ -1,96 +1,3 @@ -import { query } from "./resolvers"; -import { manifest, Query, HTTP_Query } from "./w3"; -import { RequestData, RequestError } from "./types"; +// TIP: All user-defined code lives in the module folders (./query, ./mutation) -import { - Client, - Plugin, - PluginFactory, - PluginPackageManifest, -} from "@web3api/core-js"; - -export interface GraphNodeConfig { - provider: string; -} - -export class GraphNodePlugin extends Plugin { - constructor(private _config: GraphNodeConfig) { - super(); - } - - public static manifest(): PluginPackageManifest { - return manifest; - } - - public getModules( - client: Client - ): { - query: Query.Module; - } { - return { - query: query(this, client), - }; - } - - public async query( - author: string, - name: string, - query: string, - client: Client - ): Promise { - const { data, error } = await HTTP_Query.post( - { - url: `${this._config.provider}/subgraphs/name/${author}/${name}`, - request: { - body: JSON.stringify({ - query, - }), - responseType: "TEXT", - }, - }, - client - ); - - if (error) { - throw new Error(`GraphNodePlugin: errors encountered. Error: ${error}`); - } - - if (!data) { - throw new Error(`GraphNodePlugin: data is undefined.`); - } - - if (!data.body) { - throw Error(`GraphNodePlugin: body is undefined.`); - } - - const responseJson = JSON.parse(data.body) as RequestError | RequestData; - - const responseErrors = (responseJson as RequestError).errors; - - if (responseErrors) { - throw new Error(`GraphNodePlugin: errors in query string. Errors: - ${responseErrors - .map((err) => - err.locations - ? `\n -Locations: ${err.locations - .map((loc) => `(col: ${loc.column}, line: ${loc.line})`) - .join(", ")} \n-Message: ${err.message}` - : `\n-Message: ${err.message}` - ) - .join("\n")} - `); - } - - return JSON.stringify(responseJson); - } -} - -export const graphNodePlugin: PluginFactory = ( - opts: GraphNodeConfig -) => { - return { - factory: () => new GraphNodePlugin(opts), - manifest: manifest, - }; -}; -export const plugin = graphNodePlugin; +export * from "./w3-man"; diff --git a/packages/js/plugins/graph-node/src/manifest.ts b/packages/js/plugins/graph-node/src/manifest.ts deleted file mode 100644 index ccb570ab91..0000000000 --- a/packages/js/plugins/graph-node/src/manifest.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { PluginPackageManifest } from "@web3api/core-js"; - -export const manifest: PluginPackageManifest = { - // TODO: use the schema.graphql - // https://github.com/web3-api/monorepo/issues/101 - schema: ` -type Query { - querySubgraph( - subgraphAuthor: String! - subgraphName: String! - query: String! - ): String! -} -`, - implements: [], -}; diff --git a/packages/js/plugins/graph-node/src/query/index.ts b/packages/js/plugins/graph-node/src/query/index.ts new file mode 100644 index 0000000000..098eaae4eb --- /dev/null +++ b/packages/js/plugins/graph-node/src/query/index.ts @@ -0,0 +1,59 @@ +import { Client, Module, Input_querySubgraph, HTTP_Query } from "./w3-man"; +import { RequestData, RequestError } from "./types"; + +export interface QueryConfig extends Record { + provider: string; +} + +export class Query extends Module { + public async querySubgraph( + input: Input_querySubgraph, + client: Client + ): Promise { + const { subgraphAuthor, subgraphName, query } = input; + const { data, error } = await HTTP_Query.post( + { + url: `${this.config.provider}/subgraphs/name/${subgraphAuthor}/${subgraphName}`, + request: { + body: JSON.stringify({ + query, + }), + responseType: "TEXT", + }, + }, + client + ); + + if (error) { + throw new Error(`GraphNodePlugin: errors encountered. Error: ${error}`); + } + + if (!data) { + throw new Error(`GraphNodePlugin: data is undefined.`); + } + + if (!data.body) { + throw Error(`GraphNodePlugin: body is undefined.`); + } + + const responseJson = JSON.parse(data.body) as RequestError | RequestData; + + const responseErrors = (responseJson as RequestError).errors; + + if (responseErrors) { + throw new Error(`GraphNodePlugin: errors in query string. Errors: + ${responseErrors + .map((err) => + err.locations + ? `\n -Locations: ${err.locations + .map((loc) => `(col: ${loc.column}, line: ${loc.line})`) + .join(", ")} \n-Message: ${err.message}` + : `\n-Message: ${err.message}` + ) + .join("\n")} + `); + } + + return JSON.stringify(responseJson); + } +} diff --git a/packages/js/plugins/graph-node/schema.graphql b/packages/js/plugins/graph-node/src/query/schema.graphql similarity index 100% rename from packages/js/plugins/graph-node/schema.graphql rename to packages/js/plugins/graph-node/src/query/schema.graphql diff --git a/packages/js/plugins/graph-node/src/types.ts b/packages/js/plugins/graph-node/src/query/types.ts similarity index 100% rename from packages/js/plugins/graph-node/src/types.ts rename to packages/js/plugins/graph-node/src/query/types.ts diff --git a/packages/js/plugins/graph-node/src/query/w3-man/index.ts b/packages/js/plugins/graph-node/src/query/w3-man/index.ts new file mode 100644 index 0000000000..6417838d60 --- /dev/null +++ b/packages/js/plugins/graph-node/src/query/w3-man/index.ts @@ -0,0 +1,4 @@ +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/core-js"; diff --git a/packages/js/plugins/graph-node/src/query/w3-man/module.ts b/packages/js/plugins/graph-node/src/query/w3-man/module.ts new file mode 100644 index 0000000000..10283a3a77 --- /dev/null +++ b/packages/js/plugins/graph-node/src/query/w3-man/module.ts @@ -0,0 +1,21 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as Types from "./types"; + +import { Client, PluginModule, MaybeAsync } from "@web3api/core-js"; + +export interface Input_querySubgraph extends Record { + subgraphAuthor: Types.String; + subgraphName: Types.String; + query: Types.String; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule { + abstract querySubgraph( + input: Input_querySubgraph, + client: Client + ): MaybeAsync; +} diff --git a/packages/js/plugins/graph-node/src/query/w3-man/types.ts b/packages/js/plugins/graph-node/src/query/w3-man/types.ts new file mode 100644 index 0000000000..8354c84f91 --- /dev/null +++ b/packages/js/plugins/graph-node/src/query/w3-man/types.ts @@ -0,0 +1,112 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +// @ts-ignore +import * as Types from "./"; + +// @ts-ignore +import { Client, InvokeApiResult } from "@web3api/core-js"; + +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; + +/// Imported Objects START /// + +/* URI: "ens/http.web3api.eth" */ +export interface HTTP_Request { + headers?: Array | null; + urlParams?: Array | null; + responseType: Types.HTTP_ResponseType; + body?: string | null; +} + +/* URI: "ens/http.web3api.eth" */ +export interface HTTP_Header { + key: string; + value: string; +} + +/* URI: "ens/http.web3api.eth" */ +export interface HTTP_UrlParam { + key: string; + value: string; +} + +/* URI: "ens/http.web3api.eth" */ +export interface HTTP_Response { + status: Int; + statusText: string; + headers?: Array | null; + body?: string | null; +} + +/// Imported Objects END /// + +/// Imported Enums START /// + +/* URI: "ens/http.web3api.eth" */ +export enum HTTP_ResponseTypeEnum { + TEXT, + BINARY, +} + +export type HTTP_ResponseTypeString = "TEXT" | "BINARY"; + +export type HTTP_ResponseType = HTTP_ResponseTypeEnum | HTTP_ResponseTypeString; + +/// Imported Enums END /// + +/// Imported Queries START /// + +/* URI: "ens/http.web3api.eth" */ +interface HTTP_Query_Input_get extends Record { + url: string; + request?: Types.HTTP_Request | null; +} + +/* URI: "ens/http.web3api.eth" */ +interface HTTP_Query_Input_post extends Record { + url: string; + request?: Types.HTTP_Request | null; +} + +/* URI: "ens/http.web3api.eth" */ +export const HTTP_Query = { + get: async ( + input: HTTP_Query_Input_get, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/http.web3api.eth", + module: "query", + method: "get", + input, + }); + }, + + post: async ( + input: HTTP_Query_Input_post, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/http.web3api.eth", + module: "query", + method: "post", + input, + }); + }, +}; + +/// Imported Queries END /// diff --git a/packages/js/plugins/graph-node/src/resolvers.ts b/packages/js/plugins/graph-node/src/resolvers.ts deleted file mode 100644 index dfe9527b1d..0000000000 --- a/packages/js/plugins/graph-node/src/resolvers.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { GraphNodePlugin } from "."; -import { Query } from "./w3"; - -import { Client } from "@web3api/core-js"; - -export const query = ( - graphnode: GraphNodePlugin, - client: Client -): Query.Module => ({ - querySubgraph: async (input: Query.Input_querySubgraph): Promise => { - return await graphnode.query( - input.subgraphAuthor, - input.subgraphName, - input.query, - client - ); - }, -}); diff --git a/packages/js/plugins/graph-node/src/w3-man/index.ts b/packages/js/plugins/graph-node/src/w3-man/index.ts new file mode 100644 index 0000000000..b4849fdac4 --- /dev/null +++ b/packages/js/plugins/graph-node/src/w3-man/index.ts @@ -0,0 +1,3 @@ +export * from "./schema"; +export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/js/plugins/graph-node/src/w3-man/manifest.ts b/packages/js/plugins/graph-node/src/w3-man/manifest.ts new file mode 100644 index 0000000000..41ca650b30 --- /dev/null +++ b/packages/js/plugins/graph-node/src/w3-man/manifest.ts @@ -0,0 +1,13 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +/* eslint-disable @typescript-eslint/no-unused-vars */ + +import { schema } from "./"; + +import { PluginPackageManifest } from "@web3api/core-js"; + +export const manifest: PluginPackageManifest = { + schema, + implements: [], +}; diff --git a/packages/js/plugins/graph-node/src/w3-man/plugin.ts b/packages/js/plugins/graph-node/src/w3-man/plugin.ts new file mode 100644 index 0000000000..b6616aa3ec --- /dev/null +++ b/packages/js/plugins/graph-node/src/w3-man/plugin.ts @@ -0,0 +1,41 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { Query, QueryConfig } from "../query"; +import { manifest } from "./manifest"; + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; + +export interface GraphNodePluginConfigs { + query: QueryConfig; +} + +export class GraphNodePlugin implements Plugin { + constructor(private _configs: GraphNodePluginConfigs) {} + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + query: new Query(this._configs.query), + }; + } +} + +export const graphNodePlugin: PluginFactory = ( + opts: GraphNodePluginConfigs +) => { + return { + factory: () => new GraphNodePlugin(opts), + manifest: manifest, + }; +}; + +export const plugin = graphNodePlugin; diff --git a/packages/js/plugins/graph-node/src/w3-man/schema.ts b/packages/js/plugins/graph-node/src/w3-man/schema.ts new file mode 100644 index 0000000000..d0dc54add7 --- /dev/null +++ b/packages/js/plugins/graph-node/src/w3-man/schema.ts @@ -0,0 +1,129 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export const schema = `### 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: [ + "HTTP_Query", + "HTTP_Request", + "HTTP_Header", + "HTTP_UrlParam", + "HTTP_ResponseType", + "HTTP_Response" + ] +) { + querySubgraph( + subgraphAuthor: String! + subgraphName: String! + query: String! + ): String! +} + +### Imported Queries START ### + +type HTTP_Query @imported( + uri: "ens/http.web3api.eth", + namespace: "HTTP", + nativeType: "Query" +) { + get( + url: String! + request: HTTP_Request + ): HTTP_Response + + post( + url: String! + request: HTTP_Request + ): HTTP_Response +} + +### Imported Queries END ### + +### Imported Objects START ### + +type HTTP_Request @imported( + uri: "ens/http.web3api.eth", + namespace: "HTTP", + nativeType: "Request" +) { + headers: [HTTP_Header!] + urlParams: [HTTP_UrlParam!] + responseType: HTTP_ResponseType! + body: String +} + +type HTTP_Header @imported( + uri: "ens/http.web3api.eth", + namespace: "HTTP", + nativeType: "Header" +) { + key: String! + value: String! +} + +type HTTP_UrlParam @imported( + uri: "ens/http.web3api.eth", + namespace: "HTTP", + nativeType: "UrlParam" +) { + key: String! + value: String! +} + +type HTTP_Response @imported( + uri: "ens/http.web3api.eth", + namespace: "HTTP", + nativeType: "Response" +) { + status: Int! + statusText: String! + headers: [HTTP_Header!] + body: String +} + +enum HTTP_ResponseType @imported( + uri: "ens/http.web3api.eth", + namespace: "HTTP", + nativeType: "ResponseType" +) { + TEXT + BINARY +} + +### Imported Objects END ### +`; diff --git a/packages/js/plugins/graph-node/web3api.plugin.yaml b/packages/js/plugins/graph-node/web3api.plugin.yaml index b21359a846..a997cf5e1d 100644 --- a/packages/js/plugins/graph-node/web3api.plugin.yaml +++ b/packages/js/plugins/graph-node/web3api.plugin.yaml @@ -1,3 +1,7 @@ -format: 0.0.1-prealpha.1 +format: 0.0.1-prealpha.2 language: plugin/typescript -schema: ./schema.graphql +name: GraphNode +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/js/plugins/http/package.json b/packages/js/plugins/http/package.json index e195a673ea..2306456b39 100644 --- a/packages/js/plugins/http/package.json +++ b/packages/js/plugins/http/package.json @@ -9,11 +9,12 @@ }, "main": "build/index.js", "files": [ - "build", - "schema.graphql" + "build" ], "scripts": { - "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "build": "rimraf ./build ./**/w3 ./*/**/w3 && tsc --project tsconfig.build.json", + "build:migrate": "npx w3 plugin codegen", + "build:bak": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", "codegen": "node ../../../../dependencies/node_modules/@web3api/cli/bin/w3 plugin codegen", "lint": "eslint --color -c ../../../../.eslintrc.js src/", "test": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/http/src/__tests__/e2e/e2e.spec.ts b/packages/js/plugins/http/src/__tests__/e2e/e2e.spec.ts index 904f20a12f..8bdb0f55be 100644 --- a/packages/js/plugins/http/src/__tests__/e2e/e2e.spec.ts +++ b/packages/js/plugins/http/src/__tests__/e2e/e2e.spec.ts @@ -1,5 +1,5 @@ import { httpPlugin } from "../.."; -import { Response } from "../../w3"; +import { Response } from "../../query/w3-man"; import { Web3ApiClient } from "@web3api/client-js" import nock from "nock"; @@ -19,7 +19,7 @@ describe("e2e tests for HttpPlugin", () => { plugins: [ { uri: "w3://ens/http.web3api.eth", - plugin: httpPlugin(), + plugin: httpPlugin({ query: {} }), }, ] }); 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..2469dc9ac3 100644 --- a/packages/js/plugins/http/src/__tests__/e2e/integration.spec.ts +++ b/packages/js/plugins/http/src/__tests__/e2e/integration.spec.ts @@ -1,5 +1,5 @@ import { httpPlugin } from "../.."; -import { Response } from "../../w3"; +import { Response } from "../../query/w3-man"; import { Web3ApiClient, defaultIpfsProviders } from "@web3api/client-js" import { ensPlugin } from "@web3api/ens-plugin-js"; @@ -38,7 +38,7 @@ describe("e2e tests for HttpPlugin", () => { plugins: [ { uri: "w3://ens/http.web3api.eth", - plugin: httpPlugin(), + plugin: httpPlugin({ query: {} }), }, { uri: "w3://ens/ethereum.web3api.eth", @@ -61,8 +61,10 @@ describe("e2e tests for HttpPlugin", () => { { uri: "w3://ens/ens.web3api.eth", plugin: ensPlugin({ - addresses: { - testnet: ensAddress + query: { + addresses: { + testnet: ensAddress + } } }) } diff --git a/packages/js/plugins/http/src/__tests__/unit/index.test.ts b/packages/js/plugins/http/src/__tests__/unit/index.test.ts index 7396a23954..f7426c395f 100644 --- a/packages/js/plugins/http/src/__tests__/unit/index.test.ts +++ b/packages/js/plugins/http/src/__tests__/unit/index.test.ts @@ -1,5 +1,5 @@ -import { HttpPlugin, } from "../../index"; -import { ResponseTypeEnum } from "../../w3"; +import { Query } from "../../query"; +import { ResponseTypeEnum, Client } from "../../query/w3-man"; import axios, { AxiosResponse, AxiosRequestConfig } from "axios"; @@ -17,7 +17,7 @@ describe("test http plugin", () => { }); describe("get method", () => { - const plugin: HttpPlugin = new HttpPlugin(); + const plugin = new Query({}); test("valid request: text response type", async () => { mockedAxios.get.mockResolvedValueOnce({ @@ -30,14 +30,17 @@ describe("test http plugin", () => { }, } as AxiosResponse); - const response = await plugin.get("/api/test", { - headers: [ - { key: "Accept", value: "application/json" }, - { key: "X-Test-Header", value: "test-header-value" }, - ], - urlParams: [{ key: "q", value: "test-param" }], - responseType: ResponseTypeEnum.TEXT, - }); + const response = await plugin.get({ + url: "/api/test", + request: { + headers: [ + { key: "Accept", value: "application/json" }, + { key: "X-Test-Header", value: "test-header-value" }, + ], + urlParams: [{ key: "q", value: "test-param" }], + responseType: ResponseTypeEnum.TEXT, + }, + }, {} as Client); expect(mockedAxios.get).lastCalledWith("/api/test", { headers: { @@ -48,12 +51,12 @@ describe("test http plugin", () => { responseType: "text", } as AxiosRequestConfig); - expect(response.status).toBe(200); - expect(response.statusText).toBe("Ok"); - expect(response.headers).toStrictEqual([ + expect(response?.status).toBe(200); + expect(response?.statusText).toBe("Ok"); + expect(response?.headers).toStrictEqual([ { key: "Content-Type", value: "application/json; charset=utf-8" }, ]); - expect(response.body).toBe("{result: 1001}"); + expect(response?.body).toBe("{result: 1001}"); }); test("valid request: arraybuffer response type", async () => { @@ -67,14 +70,17 @@ describe("test http plugin", () => { }, } as AxiosResponse); - const response = await plugin.get("/api/test", { - headers: [ - { key: "Accept", value: "application/json" }, - { key: "X-Test-Header", value: "test-header-value" }, - ], - urlParams: [{ key: "q", value: "test-param" }], - responseType: "BINARY", - }); + const response = await plugin.get({ + url: "/api/test", + request: { + headers: [ + { key: "Accept", value: "application/json" }, + { key: "X-Test-Header", value: "test-header-value" }, + ], + urlParams: [{ key: "q", value: "test-param" }], + responseType: "BINARY", + } + }, {} as Client); expect(mockedAxios.get).lastCalledWith("/api/test", { headers: { @@ -85,20 +91,20 @@ describe("test http plugin", () => { responseType: "arraybuffer", } as AxiosRequestConfig); - expect(response.status).toBe(200); - expect(response.statusText).toBe("Ok"); - expect(response.headers).toStrictEqual([ + expect(response?.status).toBe(200); + expect(response?.statusText).toBe("Ok"); + expect(response?.headers).toStrictEqual([ { key: "Content-Type", value: "application/json; charset=utf-8" }, ]); - expect(response.body).toBeTruthy(); - if (response.body) { + expect(response?.body).toBeTruthy(); + if (response?.body) { expect(Buffer.from(response.body, 'base64').toString()).toBe("{result: 1001}"); } }); }); describe("post method", () => { - const plugin: HttpPlugin = new HttpPlugin(); + const plugin = new Query({}); test("valid request with headers", async () => { mockedAxios.post.mockResolvedValueOnce({ @@ -111,15 +117,18 @@ describe("test http plugin", () => { }, } as AxiosResponse); - const response = await plugin.post("/api/test", { - headers: [ - { key: "Accept", value: "application/json" }, - { key: "X-Test-Header", value: "test-header-value" }, - ], - urlParams: [{ key: "q", value: "test-param" }], - body: "{request: 1001}", - responseType: "TEXT", - }); + const response = await plugin.post({ + url: "/api/test", + request: { + headers: [ + { key: "Accept", value: "application/json" }, + { key: "X-Test-Header", value: "test-header-value" }, + ], + urlParams: [{ key: "q", value: "test-param" }], + body: "{request: 1001}", + responseType: "TEXT", + } + }, {} as Client); expect(mockedAxios.post).lastCalledWith("/api/test", "{request: 1001}", { headers: { @@ -130,12 +139,12 @@ describe("test http plugin", () => { responseType: "text", } as AxiosRequestConfig); - expect(response.status).toBe(200); - expect(response.statusText).toBe("Ok"); - expect(response.headers).toStrictEqual([ + expect(response?.status).toBe(200); + expect(response?.statusText).toBe("Ok"); + expect(response?.headers).toStrictEqual([ { key: "Content-Type", value: "application/json; charset=utf-8" }, ]); - expect(response.body).toBe("{response: 1001}"); + expect(response?.body).toBe("{response: 1001}"); }); test("valid request with url params", async () => { @@ -149,15 +158,18 @@ describe("test http plugin", () => { }, } as AxiosResponse); - const response = await plugin.post("/api/test", { - headers: [ - { key: "Accept", value: "application/json" }, - { key: "X-Test-Header", value: "test-header-value" }, - ], - urlParams: [{ key: "q", value: "test-param" }], - body: "{request: 1001}", - responseType: "BINARY", - }); + const response = await plugin.post({ + url: "/api/test", + request: { + headers: [ + { key: "Accept", value: "application/json" }, + { key: "X-Test-Header", value: "test-header-value" }, + ], + urlParams: [{ key: "q", value: "test-param" }], + body: "{request: 1001}", + responseType: "BINARY", + } + }, {} as Client); expect(mockedAxios.post).lastCalledWith("/api/test", "{request: 1001}", { headers: { @@ -168,13 +180,13 @@ describe("test http plugin", () => { responseType: "arraybuffer", } as AxiosRequestConfig); - expect(response.status).toBe(200); - expect(response.statusText).toBe("Ok"); - expect(response.headers).toStrictEqual([ + expect(response?.status).toBe(200); + expect(response?.statusText).toBe("Ok"); + expect(response?.headers).toStrictEqual([ { key: "Content-Type", value: "application/json; charset=utf-8" }, ]); - expect(response.body).toBeTruthy(); - if (response.body) { + expect(response?.body).toBeTruthy(); + if (response?.body) { expect(Buffer.from(response.body, 'base64').toString()).toBe("{response: 1001}"); } }); diff --git a/packages/js/plugins/http/src/__tests__/unit/util.test.ts b/packages/js/plugins/http/src/__tests__/unit/util.test.ts index e7a3cc8275..85cc45ae48 100644 --- a/packages/js/plugins/http/src/__tests__/unit/util.test.ts +++ b/packages/js/plugins/http/src/__tests__/unit/util.test.ts @@ -1,5 +1,5 @@ -import { fromAxiosResponse, toAxiosRequestConfig } from "../../util"; -import { ResponseTypeEnum } from "../../w3"; +import { fromAxiosResponse, toAxiosRequestConfig } from "../../query/util"; +import { ResponseTypeEnum } from "../../query/w3-man"; describe("converting axios response", () => { test("response type: text", () => { diff --git a/packages/js/plugins/http/src/index.ts b/packages/js/plugins/http/src/index.ts index 7f2dd605f7..a7af0fac7a 100644 --- a/packages/js/plugins/http/src/index.ts +++ b/packages/js/plugins/http/src/index.ts @@ -1,57 +1,3 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import { query } from "./resolvers"; -import { fromAxiosResponse, toAxiosRequestConfig } from "./util"; -import { manifest, Response, Request, Query } from "./w3"; +// TIP: All user-defined code lives in the module folders (./query, ./mutation) -import axios from "axios"; -import { - Client, - Plugin, - PluginPackageManifest, - PluginPackage, -} from "@web3api/core-js"; - -export class HttpPlugin extends Plugin { - constructor() { - super(); - } - - public static manifest(): PluginPackageManifest { - return manifest; - } - - public getModules( - _client: Client - ): { - query: Query.Module; - } { - return { - query: query(this), - }; - } - - public async get(url: string, request?: Request): Promise { - const response = await axios.get( - url, - request ? toAxiosRequestConfig(request) : undefined - ); - return fromAxiosResponse(response); - } - - public async post(url: string, request?: Request): Promise { - const response = await axios.post( - url, - request ? request.body : undefined, - request ? toAxiosRequestConfig(request) : undefined - ); - return fromAxiosResponse(response); - } -} - -export const httpPlugin = (): PluginPackage => { - return { - factory: () => new HttpPlugin(), - manifest: manifest, - }; -}; -export const plugin = httpPlugin; +export * from "./w3-man"; diff --git a/packages/js/plugins/http/src/query/index.ts b/packages/js/plugins/http/src/query/index.ts new file mode 100644 index 0000000000..1e07ffec94 --- /dev/null +++ b/packages/js/plugins/http/src/query/index.ts @@ -0,0 +1,31 @@ +import { Client, Module, Input_get, Input_post, Response } from "./w3-man"; +import { fromAxiosResponse, toAxiosRequestConfig } from "./util"; + +import axios from "axios"; + +export type QueryConfig = Record; + +export class Query extends Module { + public async get( + input: Input_get, + _client: Client + ): Promise { + const response = await axios.get( + input.url, + input.request ? toAxiosRequestConfig(input.request) : undefined + ); + return fromAxiosResponse(response); + } + + public async post( + input: Input_post, + _client: Client + ): Promise { + const response = await axios.post( + input.url, + input.request ? input.request.body : undefined, + input.request ? toAxiosRequestConfig(input.request) : undefined + ); + return fromAxiosResponse(response); + } +} diff --git a/packages/js/plugins/http/schema.graphql b/packages/js/plugins/http/src/query/schema.graphql similarity index 100% rename from packages/js/plugins/http/schema.graphql rename to packages/js/plugins/http/src/query/schema.graphql diff --git a/packages/js/plugins/http/src/util.ts b/packages/js/plugins/http/src/query/util.ts similarity index 99% rename from packages/js/plugins/http/src/util.ts rename to packages/js/plugins/http/src/query/util.ts index 246d7b4609..9ef92384dc 100644 --- a/packages/js/plugins/http/src/util.ts +++ b/packages/js/plugins/http/src/query/util.ts @@ -1,4 +1,4 @@ -import { Request, Response, ResponseTypeEnum, Header } from "./w3"; +import { Request, Response, ResponseTypeEnum, Header } from "./w3-man"; import { AxiosResponse, AxiosRequestConfig } from "axios"; diff --git a/packages/js/plugins/http/src/query/w3-man/index.ts b/packages/js/plugins/http/src/query/w3-man/index.ts new file mode 100644 index 0000000000..6417838d60 --- /dev/null +++ b/packages/js/plugins/http/src/query/w3-man/index.ts @@ -0,0 +1,4 @@ +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/core-js"; diff --git a/packages/js/plugins/http/src/query/w3-man/module.ts b/packages/js/plugins/http/src/query/w3-man/module.ts new file mode 100644 index 0000000000..64b3958092 --- /dev/null +++ b/packages/js/plugins/http/src/query/w3-man/module.ts @@ -0,0 +1,30 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as Types from "./types"; + +import { Client, PluginModule, MaybeAsync } from "@web3api/core-js"; + +export interface Input_get extends Record { + url: Types.String; + request?: Types.Request | null; +} + +export interface Input_post extends Record { + url: Types.String; + request?: Types.Request | null; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule { + abstract get( + input: Input_get, + client: Client + ): MaybeAsync; + + abstract post( + input: Input_post, + client: Client + ): MaybeAsync; +} diff --git a/packages/js/plugins/http/src/query/w3-man/types.ts b/packages/js/plugins/http/src/query/w3-man/types.ts new file mode 100644 index 0000000000..39d2c61dc5 --- /dev/null +++ b/packages/js/plugins/http/src/query/w3-man/types.ts @@ -0,0 +1,53 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +// @ts-ignore +import * as Types from "./"; + +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; + +export interface Header { + key: string; + value: string; +} + +export interface UrlParam { + key: string; + value: string; +} + +export interface Response { + status: Int; + statusText: string; + headers?: Array | null; + body?: string | null; +} + +export interface Request { + headers?: Array | null; + urlParams?: Array | null; + responseType: Types.ResponseType; + body?: string | null; +} + +export enum ResponseTypeEnum { + TEXT, + BINARY, +} + +export type ResponseTypeString = "TEXT" | "BINARY"; + +export type ResponseType = ResponseTypeEnum | ResponseTypeString; diff --git a/packages/js/plugins/http/src/resolvers.ts b/packages/js/plugins/http/src/resolvers.ts deleted file mode 100644 index 924b667ec2..0000000000 --- a/packages/js/plugins/http/src/resolvers.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { HttpPlugin } from "."; -import { Query } from "./w3"; - -export const query = (http: HttpPlugin): Query.Module => ({ - get: async (input: Query.Input_get) => { - return await http.get(input.url, input.request || undefined); - }, - post: async (input: Query.Input_post) => { - return await http.post(input.url, input.request || undefined); - }, -}); diff --git a/packages/js/plugins/http/src/w3-man/index.ts b/packages/js/plugins/http/src/w3-man/index.ts new file mode 100644 index 0000000000..b4849fdac4 --- /dev/null +++ b/packages/js/plugins/http/src/w3-man/index.ts @@ -0,0 +1,3 @@ +export * from "./schema"; +export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/js/plugins/http/src/w3-man/manifest.ts b/packages/js/plugins/http/src/w3-man/manifest.ts new file mode 100644 index 0000000000..41ca650b30 --- /dev/null +++ b/packages/js/plugins/http/src/w3-man/manifest.ts @@ -0,0 +1,13 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +/* eslint-disable @typescript-eslint/no-unused-vars */ + +import { schema } from "./"; + +import { PluginPackageManifest } from "@web3api/core-js"; + +export const manifest: PluginPackageManifest = { + schema, + implements: [], +}; diff --git a/packages/js/plugins/http/src/w3-man/plugin.ts b/packages/js/plugins/http/src/w3-man/plugin.ts new file mode 100644 index 0000000000..ad8dce9371 --- /dev/null +++ b/packages/js/plugins/http/src/w3-man/plugin.ts @@ -0,0 +1,41 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { Query, QueryConfig } from "../query"; +import { manifest } from "./manifest"; + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; + +export interface HttpPluginConfigs { + query: QueryConfig; +} + +export class HttpPlugin implements Plugin { + constructor(private _configs: HttpPluginConfigs) {} + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + query: new Query(this._configs.query), + }; + } +} + +export const httpPlugin: PluginFactory = ( + opts: HttpPluginConfigs +) => { + return { + factory: () => new HttpPlugin(opts), + manifest: manifest, + }; +}; + +export const plugin = httpPlugin; diff --git a/packages/js/plugins/http/src/w3-man/schema.ts b/packages/js/plugins/http/src/w3-man/schema.ts new file mode 100644 index 0000000000..15d3453797 --- /dev/null +++ b/packages/js/plugins/http/src/w3-man/schema.ts @@ -0,0 +1,88 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export const schema = `### 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 { + get( + url: String! + request: Request + ): Response + + post( + url: String! + request: Request + ): Response +} + +type Header { + key: String! + value: String! +} + +type UrlParam { + key: String! + value: String! +} + +type Response { + status: Int! + statusText: String! + headers: [Header!] + body: String +} + +type Request { + headers: [Header!] + urlParams: [UrlParam!] + responseType: ResponseType! + body: String +} + +enum ResponseType { + TEXT + BINARY +} + +### Imported Queries START ### + +### Imported Queries END ### + +### Imported Objects START ### + +### Imported Objects END ### +`; diff --git a/packages/js/plugins/http/web3api.plugin.yaml b/packages/js/plugins/http/web3api.plugin.yaml index b21359a846..d47eb47fa6 100644 --- a/packages/js/plugins/http/web3api.plugin.yaml +++ b/packages/js/plugins/http/web3api.plugin.yaml @@ -1,3 +1,7 @@ -format: 0.0.1-prealpha.1 +format: 0.0.1-prealpha.2 language: plugin/typescript -schema: ./schema.graphql +name: Http +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/js/plugins/ipfs/package.json b/packages/js/plugins/ipfs/package.json index b5f0df49ea..443d956990 100644 --- a/packages/js/plugins/ipfs/package.json +++ b/packages/js/plugins/ipfs/package.json @@ -9,11 +9,12 @@ }, "main": "build/index.js", "files": [ - "build", - "schema.graphql" + "build" ], "scripts": { - "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "build": "rimraf ./build ./**/w3 ./*/**/w3 && tsc --project tsconfig.build.json", + "build:migrate": "npx w3 plugin codegen", + "build:bak": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", "codegen": "node ../../../../dependencies/node_modules/@web3api/cli/bin/w3 plugin codegen", "lint": "eslint --color -c ../../../../.eslintrc.js src/", "test": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/ipfs/src/types/IpfsClient.ts b/packages/js/plugins/ipfs/src/common/IpfsClient.ts similarity index 100% rename from packages/js/plugins/ipfs/src/types/IpfsClient.ts rename to packages/js/plugins/ipfs/src/common/IpfsClient.ts diff --git a/packages/js/plugins/ipfs/src/common/IpfsConfig.ts b/packages/js/plugins/ipfs/src/common/IpfsConfig.ts new file mode 100644 index 0000000000..bb55fd34e0 --- /dev/null +++ b/packages/js/plugins/ipfs/src/common/IpfsConfig.ts @@ -0,0 +1,4 @@ +export interface IpfsConfig { + provider: string; + fallbackProviders?: string[]; +} diff --git a/packages/js/plugins/ipfs/src/exec/abortable.ts b/packages/js/plugins/ipfs/src/common/exec/abortable.ts similarity index 97% rename from packages/js/plugins/ipfs/src/exec/abortable.ts rename to packages/js/plugins/ipfs/src/common/exec/abortable.ts index d6a16b78ad..47d276c310 100644 --- a/packages/js/plugins/ipfs/src/exec/abortable.ts +++ b/packages/js/plugins/ipfs/src/common/exec/abortable.ts @@ -1,4 +1,4 @@ -import { IpfsClient } from "../types/IpfsClient"; +import { IpfsClient } from "../IpfsClient"; import AbortController from "abort-controller"; diff --git a/packages/js/plugins/ipfs/src/exec/fallbacks.ts b/packages/js/plugins/ipfs/src/common/exec/fallbacks.ts similarity index 99% rename from packages/js/plugins/ipfs/src/exec/fallbacks.ts rename to packages/js/plugins/ipfs/src/common/exec/fallbacks.ts index d48db6aa10..78606a312c 100644 --- a/packages/js/plugins/ipfs/src/exec/fallbacks.ts +++ b/packages/js/plugins/ipfs/src/common/exec/fallbacks.ts @@ -1,4 +1,4 @@ -import { IpfsClient } from "../types/IpfsClient"; +import { IpfsClient } from "../IpfsClient"; import { execAbortable, AbortablePromise } from "./abortable"; // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, @typescript-eslint/naming-convention diff --git a/packages/js/plugins/ipfs/src/exec/index.ts b/packages/js/plugins/ipfs/src/common/exec/index.ts similarity index 100% rename from packages/js/plugins/ipfs/src/exec/index.ts rename to packages/js/plugins/ipfs/src/common/exec/index.ts diff --git a/packages/js/plugins/ipfs/src/exec/simple.ts b/packages/js/plugins/ipfs/src/common/exec/simple.ts similarity index 93% rename from packages/js/plugins/ipfs/src/exec/simple.ts rename to packages/js/plugins/ipfs/src/common/exec/simple.ts index 1680cdb075..086bc6fba7 100644 --- a/packages/js/plugins/ipfs/src/exec/simple.ts +++ b/packages/js/plugins/ipfs/src/common/exec/simple.ts @@ -1,4 +1,4 @@ -import { IpfsClient } from "../types/IpfsClient"; +import { IpfsClient } from "../IpfsClient"; import { execAbortable } from "./abortable"; // Executes function in a try catch and returns error (if any) and result diff --git a/packages/js/plugins/ipfs/src/index.ts b/packages/js/plugins/ipfs/src/index.ts index b68a74aeff..36153b628e 100644 --- a/packages/js/plugins/ipfs/src/index.ts +++ b/packages/js/plugins/ipfs/src/index.ts @@ -1,161 +1,31 @@ -import { query, mutation } from "./resolvers"; -import { manifest, Query, Mutation, Options, ResolveResult } from "./w3"; -import { IpfsClient } from "./types/IpfsClient"; -import { execSimple, execFallbacks } from "./exec"; +// TIP: All user-defined code lives in the module folders (./query, ./mutation) -import { - Client, - Plugin, - PluginFactory, - PluginPackageManifest, -} from "@web3api/core-js"; -import CID from "cids"; +import * as Internal from "./w3-man"; +import { IpfsConfig } from "./common/IpfsConfig"; -// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports -const isIPFS = require("is-ipfs"); -// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, @typescript-eslint/naming-convention -const createIpfsClient = require("@dorgjelli-test/ipfs-http-client-lite"); +import { PluginFactory } from "@web3api/core-js"; -export interface IpfsConfig { - provider: string; - fallbackProviders?: string[]; -} - -export class IpfsPlugin extends Plugin { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore: initialized within setProvider - private _ipfs: IpfsClient; - - constructor(private _config: IpfsConfig) { - super(); - this.setProvider(this._config.provider); - } - - public static manifest(): PluginPackageManifest { - return manifest; - } - - public static isCID(cid: string): boolean { - return isIPFS.cid(cid) || isIPFS.cidPath(cid) || isIPFS.ipfsPath(cid); - } - - public getModules( - _client: Client - ): { - query: Query.Module; - mutation: Mutation.Module; - } { - return { - query: query(this), - mutation: mutation(this), - }; - } - - public setProvider(provider: string): void { - this._config.provider = provider; - this._ipfs = createIpfsClient(provider); - } - - public async add( - data: Uint8Array - ): Promise<{ - name: string; - hash: CID; - }> { - const result = await this._ipfs.add(data); +export { manifest, schema } from "./w3-man"; - if (result.length === 0) { - throw Error( - `IpfsPlugin:add failed to add contents. Result of length 0 returned.` - ); - } +export interface IpfsPluginConfigs + extends IpfsConfig, + Record {} - return result[0]; - } - - public async cat(cid: string, options?: Options): Promise { - return await this._execWithOptions( - "cat", - (ipfs: IpfsClient, _provider: string, options: unknown) => { - return ipfs.cat(cid, options); - }, - options - ); - } - - public async catToString(cid: string, options?: Options): Promise { - const buffer = await this.cat(cid, options); - return buffer.toString("utf-8"); - } - - public async resolve(cid: string, options?: Options): Promise { - return await this._execWithOptions( - "resolve", - async (ipfs: IpfsClient, provider: string, options: unknown) => { - const { path } = await ipfs.resolve(cid, options); - return { - cid: path, - provider, - }; - }, - options - ); - } - - private async _execWithOptions( - operation: string, - func: ( - ipfs: IpfsClient, - provider: string, - options: unknown - ) => Promise, - options?: Options - ): Promise { - if (!options) { - // Default behavior if no options are provided - return await execSimple( - operation, - this._ipfs, - this._config.provider, - 0, - func - ); - } - - const timeout = options.timeout || 0; - - let providers = [ - this._config.provider, - ...(this._config.fallbackProviders || []), - ]; - let ipfs = this._ipfs; - let defaultProvider = this._config.provider; - - // Use the provider defaul toverride specified - if (options.provider) { - providers = [options.provider, ...providers]; - ipfs = createIpfsClient(options.provider); - defaultProvider = options.provider; - } - - return await execFallbacks( - operation, - ipfs, - defaultProvider, - providers, - timeout, - func, - { - parallel: !options.disableParallelRequests, - } - ); +export class IpfsPlugin extends Internal.IpfsPlugin { + constructor(config: IpfsPluginConfigs) { + super({ + query: config, + mutation: config, + }); } } -export const ipfsPlugin: PluginFactory = (opts: IpfsConfig) => { - return { - factory: () => new IpfsPlugin(opts), - manifest: manifest, - }; -}; +export const ipfsPlugin: PluginFactory = ( + opts: IpfsPluginConfigs +) => + Internal.ipfsPlugin({ + query: opts, + mutation: opts, + }); + export const plugin = ipfsPlugin; diff --git a/packages/js/plugins/ipfs/src/mutation/index.ts b/packages/js/plugins/ipfs/src/mutation/index.ts new file mode 100644 index 0000000000..14f315d981 --- /dev/null +++ b/packages/js/plugins/ipfs/src/mutation/index.ts @@ -0,0 +1,31 @@ +import { Module, Input_addFile } from "./w3-man"; +import { IpfsConfig } from "../common/IpfsConfig"; +import { IpfsClient } from "../common/IpfsClient"; + +// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, @typescript-eslint/naming-convention +const createIpfsClient = require("@dorgjelli-test/ipfs-http-client-lite"); + +export interface MutationConfig extends IpfsConfig, Record {} + +export class Mutation extends Module { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore: initialized within setProvider + private _ipfs: IpfsClient; + + constructor(config: MutationConfig) { + super(config); + this._ipfs = createIpfsClient(this.config.provider); + } + + public async addFile(input: Input_addFile): Promise { + const result = await this._ipfs.add(input.data); + + if (result.length === 0) { + throw Error( + `IpfsPlugin:add failed to add contents. Result of length 0 returned.` + ); + } + + return result[0].hash.toString(); + } +} diff --git a/packages/js/plugins/ipfs/src/mutation/schema.graphql b/packages/js/plugins/ipfs/src/mutation/schema.graphql new file mode 100644 index 0000000000..73aecfd62a --- /dev/null +++ b/packages/js/plugins/ipfs/src/mutation/schema.graphql @@ -0,0 +1,5 @@ +type Mutation { + # TODO: Allow for custom type CID + # https://github.com/web3-api/monorepo/issues/103 + addFile(data: Bytes!): String! +} diff --git a/packages/js/plugins/ipfs/src/mutation/w3-man/index.ts b/packages/js/plugins/ipfs/src/mutation/w3-man/index.ts new file mode 100644 index 0000000000..6417838d60 --- /dev/null +++ b/packages/js/plugins/ipfs/src/mutation/w3-man/index.ts @@ -0,0 +1,4 @@ +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/core-js"; diff --git a/packages/js/plugins/ipfs/src/mutation/w3-man/module.ts b/packages/js/plugins/ipfs/src/mutation/w3-man/module.ts new file mode 100644 index 0000000000..c1103cc03a --- /dev/null +++ b/packages/js/plugins/ipfs/src/mutation/w3-man/module.ts @@ -0,0 +1,19 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as Types from "./types"; + +import { Client, PluginModule, MaybeAsync } from "@web3api/core-js"; + +export interface Input_addFile extends Record { + data: Types.Bytes; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule { + abstract addFile( + input: Input_addFile, + client: Client + ): MaybeAsync; +} diff --git a/packages/js/plugins/ipfs/src/mutation/w3-man/types.ts b/packages/js/plugins/ipfs/src/mutation/w3-man/types.ts new file mode 100644 index 0000000000..e6af7e5e03 --- /dev/null +++ b/packages/js/plugins/ipfs/src/mutation/w3-man/types.ts @@ -0,0 +1,13 @@ +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; diff --git a/packages/js/plugins/ipfs/src/query/index.ts b/packages/js/plugins/ipfs/src/query/index.ts new file mode 100644 index 0000000000..9c16d4627c --- /dev/null +++ b/packages/js/plugins/ipfs/src/query/index.ts @@ -0,0 +1,205 @@ +import { + Module, + Input_catFile, + Input_resolve, + Input_tryResolveUri, + Input_getFile, + Bytes, + Options, + ResolveResult, + QueryEnv, + UriResolver_MaybeUriOrManifest, +} from "./w3-man"; +import { IpfsConfig } from "../common/IpfsConfig"; +import { IpfsClient } from "../common/IpfsClient"; +import { execSimple, execFallbacks } from "../common/exec"; + +// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports +const isIPFS = require("is-ipfs"); +// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, @typescript-eslint/naming-convention +const createIpfsClient = require("@dorgjelli-test/ipfs-http-client-lite"); + +const getOptions = ( + input: Options | undefined | null, + env: QueryEnv +): Options => { + const options = input || {}; + + if ( + options.disableParallelRequests === undefined || + options.disableParallelRequests === null + ) { + options.disableParallelRequests = env.disableParallelRequests; + } + + return options; +}; + +export interface QueryConfig extends IpfsConfig, Record {} + +export class Query extends Module { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore: initialized within setProvider + private _ipfs: IpfsClient; + + constructor(config: QueryConfig) { + super(config); + this._ipfs = createIpfsClient(this.config.provider); + } + + public static isCID(cid: string): boolean { + return isIPFS.cid(cid) || isIPFS.cidPath(cid) || isIPFS.ipfsPath(cid); + } + + public async cat(cid: string, options?: Options): Promise { + return await this._execWithOptions( + "cat", + (ipfs: IpfsClient, _provider: string, options: unknown) => { + return ipfs.cat(cid, options); + }, + options + ); + } + + public async catToString(cid: string, options?: Options): Promise { + const buffer = await this.cat(cid, options); + return buffer.toString("utf-8"); + } + + public async catFile(input: Input_catFile): Promise { + const options = getOptions(input.options, this.env); + return await this.cat(input.cid, options); + } + + public async resolve(input: Input_resolve): Promise { + const options = getOptions(input.options, this.env); + return await this._execWithOptions( + "resolve", + async (ipfs: IpfsClient, provider: string, options: unknown) => { + const { path } = await ipfs.resolve(input.cid, options); + return { + cid: path, + provider, + }; + }, + options + ); + } + + // uri-resolver.core.web3api.eth + public async tryResolveUri( + input: Input_tryResolveUri + ): Promise { + if (input.authority !== "ipfs") { + return null; + } + + if (!Query.isCID(input.path)) { + // Not a valid CID + return { manifest: null, uri: null }; + } + + const manifestSearchPatterns = [ + "web3api.json", + "web3api.yaml", + "web3api.yml", + ]; + + let manifest: string | undefined; + + for (const manifestSearchPattern of manifestSearchPatterns) { + try { + manifest = await this.catToString( + `${input.path}/${manifestSearchPattern}`, + { + timeout: 5000, + disableParallelRequests: this.env.disableParallelRequests, + } + ); + } catch (e) { + // TODO: logging + // https://github.com/web3-api/monorepo/issues/33 + } + } + + if (manifest) { + return { uri: null, manifest }; + } else { + // Noting found + return { uri: null, manifest: null }; + } + } + + public async getFile(input: Input_getFile): Promise { + try { + const result = await this.resolve({ + cid: input.path, + options: { + timeout: 5000, + disableParallelRequests: this.env.disableParallelRequests, + }, + }); + + if (!result) { + return null; + } + + return await this.cat(result.cid, { + provider: result.provider, + timeout: 20000, + disableParallelRequests: true, + }); + } catch (e) { + return null; + } + } + + private async _execWithOptions( + operation: string, + func: ( + ipfs: IpfsClient, + provider: string, + options: unknown + ) => Promise, + options?: Options + ): Promise { + if (!options) { + // Default behavior if no options are provided + return await execSimple( + operation, + this._ipfs, + this.config.provider, + 0, + func + ); + } + + const timeout = options.timeout || 0; + + let providers = [ + this.config.provider, + ...(this.config.fallbackProviders || []), + ]; + let ipfs = this._ipfs; + let defaultProvider = this.config.provider; + + // Use the provider defaul toverride specified + if (options.provider) { + providers = [options.provider, ...providers]; + ipfs = createIpfsClient(options.provider); + defaultProvider = options.provider; + } + + return await execFallbacks( + operation, + ipfs, + defaultProvider, + providers, + timeout, + func, + { + parallel: !options.disableParallelRequests, + } + ); + } +} diff --git a/packages/js/plugins/ipfs/schema.graphql b/packages/js/plugins/ipfs/src/query/schema.graphql similarity index 84% rename from packages/js/plugins/ipfs/schema.graphql rename to packages/js/plugins/ipfs/src/query/schema.graphql index 14842d1e6f..a0719405e0 100644 --- a/packages/js/plugins/ipfs/schema.graphql +++ b/packages/js/plugins/ipfs/src/query/schema.graphql @@ -1,5 +1,12 @@ #import { Query, MaybeUriOrManifest } into UriResolver from "ens/uri-resolver.core.web3api.eth" +type QueryEnv { + """ + Disable querying providers in parallel when resolving URIs + """ + disableParallelRequests: Boolean +} + type Query implements UriResolver_Query { catFile( cid: String! @@ -12,12 +19,6 @@ type Query implements UriResolver_Query { ): ResolveResult } -type Mutation { - # TODO: Allow for custom type CID - # https://github.com/web3-api/monorepo/issues/103 - addFile(data: Bytes!): String! -} - type ResolveResult { cid: String! provider: String! @@ -40,10 +41,3 @@ type Options { """ disableParallelRequests: Boolean } - -type QueryEnv { - """ - Disable querying providers in parallel when resolving URIs - """ - disableParallelRequests: Boolean -} \ No newline at end of file diff --git a/packages/js/plugins/ipfs/src/query/w3-man/index.ts b/packages/js/plugins/ipfs/src/query/w3-man/index.ts new file mode 100644 index 0000000000..6417838d60 --- /dev/null +++ b/packages/js/plugins/ipfs/src/query/w3-man/index.ts @@ -0,0 +1,4 @@ +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/core-js"; diff --git a/packages/js/plugins/ipfs/src/query/w3-man/module.ts b/packages/js/plugins/ipfs/src/query/w3-man/module.ts new file mode 100644 index 0000000000..a9f58c2430 --- /dev/null +++ b/packages/js/plugins/ipfs/src/query/w3-man/module.ts @@ -0,0 +1,49 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as Types from "./types"; + +import { Client, PluginModule, MaybeAsync } from "@web3api/core-js"; + +export interface Input_catFile extends Record { + cid: Types.String; + options?: Types.Options | null; +} + +export interface Input_resolve extends Record { + cid: Types.String; + options?: Types.Options | null; +} + +export interface Input_tryResolveUri extends Record { + authority: Types.String; + path: Types.String; +} + +export interface Input_getFile extends Record { + path: Types.String; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule { + abstract catFile( + input: Input_catFile, + client: Client + ): MaybeAsync; + + abstract resolve( + input: Input_resolve, + client: Client + ): MaybeAsync; + + abstract tryResolveUri( + input: Input_tryResolveUri, + client: Client + ): MaybeAsync; + + abstract getFile( + input: Input_getFile, + client: Client + ): MaybeAsync; +} diff --git a/packages/js/plugins/ipfs/src/query/w3-man/types.ts b/packages/js/plugins/ipfs/src/query/w3-man/types.ts new file mode 100644 index 0000000000..2cdf005b0b --- /dev/null +++ b/packages/js/plugins/ipfs/src/query/w3-man/types.ts @@ -0,0 +1,91 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +// @ts-ignore +import * as Types from "./"; + +// @ts-ignore +import { Client, InvokeApiResult } from "@web3api/core-js"; + +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; + +export interface QueryEnv extends Record { + disableParallelRequests?: boolean | null; +} + +export interface ResolveResult { + cid: string; + provider: string; +} + +export interface Options { + timeout?: UInt32 | null; + provider?: string | null; + disableParallelRequests?: boolean | null; +} + +/// Imported Objects START /// + +/* URI: "ens/uri-resolver.core.web3api.eth" */ +export interface UriResolver_MaybeUriOrManifest { + uri?: string | null; + manifest?: string | null; +} + +/// Imported Objects END /// + +/// Imported Queries START /// + +/* URI: "ens/uri-resolver.core.web3api.eth" */ +interface UriResolver_Query_Input_tryResolveUri + extends Record { + authority: string; + path: string; +} + +/* URI: "ens/uri-resolver.core.web3api.eth" */ +interface UriResolver_Query_Input_getFile extends Record { + path: string; +} + +/* URI: "ens/uri-resolver.core.web3api.eth" */ +export const UriResolver_Query = { + tryResolveUri: async ( + input: UriResolver_Query_Input_tryResolveUri, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/uri-resolver.core.web3api.eth", + module: "query", + method: "tryResolveUri", + input, + }); + }, + + getFile: async ( + input: UriResolver_Query_Input_getFile, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/uri-resolver.core.web3api.eth", + module: "query", + method: "getFile", + input, + }); + }, +}; + +/// Imported Queries END /// diff --git a/packages/js/plugins/ipfs/src/resolvers.ts b/packages/js/plugins/ipfs/src/resolvers.ts deleted file mode 100644 index e50a6ba71f..0000000000 --- a/packages/js/plugins/ipfs/src/resolvers.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { IpfsPlugin } from "./"; -import { ResolveResult, Options, Query, Mutation, QueryEnv } from "./w3"; - -const getOptions = ( - input: Options | undefined | null, - env: QueryEnv -): Options => { - const options = input || {}; - - if ( - options.disableParallelRequests === undefined || - options.disableParallelRequests === null - ) { - options.disableParallelRequests = env.disableParallelRequests; - } - - return options; -}; - -export const query = (ipfs: IpfsPlugin): Query.Module => ({ - catFile: async (input: Query.Input_catFile) => { - const queryEnv = ipfs.getEnv("query") as QueryEnv; - const options = getOptions(input.options, queryEnv); - return await ipfs.cat(input.cid, options); - }, - resolve: async (input: Query.Input_resolve): Promise => { - const queryEnv = ipfs.getEnv("query") as QueryEnv; - const options = getOptions(input.options, queryEnv); - return await ipfs.resolve(input.cid, options); - }, - // uri-resolver.core.web3api.eth - tryResolveUri: async (input: Query.Input_tryResolveUri) => { - const queryEnv = ipfs.getEnv("query") as QueryEnv; - - if (input.authority !== "ipfs") { - return null; - } - - if (!IpfsPlugin.isCID(input.path)) { - // Not a valid CID - return { manifest: null, uri: null }; - } - - const manifestSearchPatterns = [ - "web3api.json", - "web3api.yaml", - "web3api.yml", - ]; - - let manifest: string | undefined; - - for (const manifestSearchPattern of manifestSearchPatterns) { - try { - manifest = await ipfs.catToString( - `${input.path}/${manifestSearchPattern}`, - { - timeout: 5000, - disableParallelRequests: queryEnv.disableParallelRequests, - } - ); - } catch (e) { - // TODO: logging - // https://github.com/web3-api/monorepo/issues/33 - } - } - - if (manifest) { - return { uri: null, manifest }; - } else { - // Noting found - return { uri: null, manifest: null }; - } - }, - getFile: async (input: Query.Input_getFile) => { - const queryEnv = ipfs.getEnv("query") as QueryEnv; - - try { - const { cid, provider } = await ipfs.resolve(input.path, { - timeout: 5000, - disableParallelRequests: queryEnv.disableParallelRequests, - }); - - return await ipfs.cat(cid, { - provider, - timeout: 20000, - disableParallelRequests: true, - }); - } catch (e) { - return null; - } - }, -}); - -export const mutation = (ipfs: IpfsPlugin): Mutation.Module => ({ - addFile: async (input: Mutation.Input_addFile) => { - const { hash } = await ipfs.add(input.data); - return hash.toString(); - }, -}); diff --git a/packages/js/plugins/ipfs/src/w3-man/index.ts b/packages/js/plugins/ipfs/src/w3-man/index.ts new file mode 100644 index 0000000000..b4849fdac4 --- /dev/null +++ b/packages/js/plugins/ipfs/src/w3-man/index.ts @@ -0,0 +1,3 @@ +export * from "./schema"; +export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/js/plugins/ipfs/src/w3-man/manifest.ts b/packages/js/plugins/ipfs/src/w3-man/manifest.ts new file mode 100644 index 0000000000..278a2d0d7f --- /dev/null +++ b/packages/js/plugins/ipfs/src/w3-man/manifest.ts @@ -0,0 +1,15 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +import { schema } from "./"; + +// @ts-ignore +import { PluginPackageManifest, Uri } from "@web3api/core-js"; + +export const manifest: PluginPackageManifest = { + schema, + implements: [new Uri("ens/uri-resolver.core.web3api.eth")], +}; diff --git a/packages/js/plugins/ipfs/src/w3-man/plugin.ts b/packages/js/plugins/ipfs/src/w3-man/plugin.ts new file mode 100644 index 0000000000..a4974478c3 --- /dev/null +++ b/packages/js/plugins/ipfs/src/w3-man/plugin.ts @@ -0,0 +1,44 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { Query, QueryConfig } from "../query"; +import { Mutation, MutationConfig } from "../mutation"; +import { manifest } from "./manifest"; + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; + +export interface IpfsPluginConfigs { + query: QueryConfig; + mutation: MutationConfig; +} + +export class IpfsPlugin implements Plugin { + constructor(private _configs: IpfsPluginConfigs) {} + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + query: new Query(this._configs.query), + mutation: new Mutation(this._configs.mutation), + }; + } +} + +export const ipfsPlugin: PluginFactory = ( + opts: IpfsPluginConfigs +) => { + return { + factory: () => new IpfsPlugin(opts), + manifest: manifest, + }; +}; + +export const plugin = ipfsPlugin; diff --git a/packages/js/plugins/ipfs/src/w3-man/schema.ts b/packages/js/plugins/ipfs/src/w3-man/schema.ts new file mode 100644 index 0000000000..c0b3ad56fd --- /dev/null +++ b/packages/js/plugins/ipfs/src/w3-man/schema.ts @@ -0,0 +1,136 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export const schema = `### 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 implements UriResolver_Query @imports( + types: [ + "UriResolver_Query", + "UriResolver_MaybeUriOrManifest" + ] +) { + catFile( + cid: String! + options: Options + ): Bytes! + + resolve( + cid: String! + options: Options + ): ResolveResult + + tryResolveUri( + authority: String! + path: String! + ): UriResolver_MaybeUriOrManifest + + getFile( + path: String! + ): Bytes +} + +type Mutation @imports( + types: [ + "UriResolver_Query", + "UriResolver_MaybeUriOrManifest" + ] +) { + addFile( + data: Bytes! + ): String! +} + +type QueryEnv { + """ + Disable querying providers in parallel when resolving URIs + """ + disableParallelRequests: Boolean +} + +type ResolveResult { + cid: String! + provider: String! +} + +type Options { + """ + Timeout (in ms) for the operation. +Fallback providers are used if timeout is reached. + """ + timeout: UInt32 + """ + The IPFS provider to be used + """ + provider: String + """ + Disable querying providers in parallel when resolving URIs + """ + disableParallelRequests: Boolean +} + +### Imported Queries START ### + +type UriResolver_Query @imported( + uri: "ens/uri-resolver.core.web3api.eth", + namespace: "UriResolver", + nativeType: "Query" +) { + tryResolveUri( + authority: String! + path: String! + ): UriResolver_MaybeUriOrManifest + + getFile( + path: String! + ): Bytes +} + +### Imported Queries END ### + +### Imported Objects START ### + +type UriResolver_MaybeUriOrManifest @imported( + uri: "ens/uri-resolver.core.web3api.eth", + namespace: "UriResolver", + nativeType: "MaybeUriOrManifest" +) { + uri: String + manifest: String +} + +### Imported Objects END ### +`; diff --git a/packages/js/plugins/ipfs/web3api.plugin.yaml b/packages/js/plugins/ipfs/web3api.plugin.yaml index fdc1da92f3..f1d37ba521 100644 --- a/packages/js/plugins/ipfs/web3api.plugin.yaml +++ b/packages/js/plugins/ipfs/web3api.plugin.yaml @@ -1,6 +1,13 @@ -format: 0.0.1-prealpha.1 +format: 0.0.1-prealpha.2 +name: Ipfs language: plugin/typescript -schema: ./schema.graphql +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts import_redirects: - uri: "ens/uri-resolver.core.web3api.eth" schema: ../../../core-interfaces/uri-resolver/src/query.graphql diff --git a/packages/js/plugins/logger/package.json b/packages/js/plugins/logger/package.json index 721bbfea23..0906e74363 100644 --- a/packages/js/plugins/logger/package.json +++ b/packages/js/plugins/logger/package.json @@ -7,13 +7,14 @@ "url": "https://github.com/web3-api/monorepo.git" }, "files": [ - "build", - "schema.graphql" + "build" ], "version": "0.0.1-prealpha.71", "main": "build/index.js", "scripts": { - "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "build": "rimraf ./build ./**/w3 ./*/**/w3 && tsc --project tsconfig.build.json", + "build:migrate": "npx w3 plugin codegen", + "build:bak": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", "codegen": "node ../../../../dependencies/node_modules/@web3api/cli/bin/w3 plugin codegen", "lint": "eslint --color -c ../../../../.eslintrc.js src/", "test": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/logger/src/index.ts b/packages/js/plugins/logger/src/index.ts index f16d52afb9..a7af0fac7a 100644 --- a/packages/js/plugins/logger/src/index.ts +++ b/packages/js/plugins/logger/src/index.ts @@ -1,64 +1,3 @@ -import { query } from "./resolvers"; -import { manifest, Query, Logger_LogLevel, Logger_LogLevelEnum } from "./w3"; +// TIP: All user-defined code lives in the module folders (./query, ./mutation) -import { Plugin, PluginPackageManifest, PluginPackage } from "@web3api/core-js"; - -export type LogFunc = (level: Logger_LogLevel, message: string) => boolean; - -export class LoggerPlugin extends Plugin { - private _logFunc?: LogFunc; - - constructor(logFunc?: LogFunc) { - super(); - this._logFunc = logFunc; - } - - public static manifest(): PluginPackageManifest { - return manifest; - } - - public getModules(): { - query: Query.Module; - } { - return { - query: query(this), - }; - } - - public log(level: Logger_LogLevel, message: string): boolean { - if (this._logFunc) { - return this._logFunc(level, message); - } - - switch (level) { - case "DEBUG": - case Logger_LogLevelEnum.DEBUG: - console.debug(message); - break; - case "WARN": - case Logger_LogLevelEnum.WARN: - console.warn(message); - break; - case "ERROR": - case Logger_LogLevelEnum.ERROR: - console.error(message); - break; - case "INFO": - case Logger_LogLevelEnum.INFO: - console.log(message); - break; - default: - console.log(message); - } - - return true; - } -} - -export const loggerPlugin = (): PluginPackage => { - return { - factory: () => new LoggerPlugin(), - manifest: manifest, - }; -}; -export const plugin = loggerPlugin; +export * from "./w3-man"; diff --git a/packages/js/plugins/logger/src/query/index.ts b/packages/js/plugins/logger/src/query/index.ts new file mode 100644 index 0000000000..1ef7fd45b3 --- /dev/null +++ b/packages/js/plugins/logger/src/query/index.ts @@ -0,0 +1,43 @@ +import { + Module, + Input_log, + Logger_LogLevel, + Logger_LogLevelEnum, +} from "./w3-man"; + +export type LogFunc = (level: Logger_LogLevel, message: string) => boolean; + +export interface QueryConfig extends Record { + logFunc?: LogFunc; +} + +export class Query extends Module { + public log(input: Input_log): boolean { + if (this.config.logFunc) { + return this.config.logFunc(input.level, input.message); + } + + switch (input.level) { + case "DEBUG": + case Logger_LogLevelEnum.DEBUG: + console.debug(input.message); + break; + case "WARN": + case Logger_LogLevelEnum.WARN: + console.warn(input.message); + break; + case "ERROR": + case Logger_LogLevelEnum.ERROR: + console.error(input.message); + break; + case "INFO": + case Logger_LogLevelEnum.INFO: + console.log(input.message); + break; + default: + console.log(input.message); + } + + return true; + } +} diff --git a/packages/js/plugins/logger/schema.graphql b/packages/js/plugins/logger/src/query/schema.graphql similarity index 100% rename from packages/js/plugins/logger/schema.graphql rename to packages/js/plugins/logger/src/query/schema.graphql diff --git a/packages/js/plugins/logger/src/query/w3-man/index.ts b/packages/js/plugins/logger/src/query/w3-man/index.ts new file mode 100644 index 0000000000..6417838d60 --- /dev/null +++ b/packages/js/plugins/logger/src/query/w3-man/index.ts @@ -0,0 +1,4 @@ +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/core-js"; diff --git a/packages/js/plugins/logger/src/query/w3-man/module.ts b/packages/js/plugins/logger/src/query/w3-man/module.ts new file mode 100644 index 0000000000..b310d469d1 --- /dev/null +++ b/packages/js/plugins/logger/src/query/w3-man/module.ts @@ -0,0 +1,17 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as Types from "./types"; + +import { Client, PluginModule, MaybeAsync } from "@web3api/core-js"; + +export interface Input_log extends Record { + level: Types.Logger_LogLevel; + message: Types.String; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule { + abstract log(input: Input_log, client: Client): MaybeAsync; +} diff --git a/packages/js/plugins/logger/src/query/w3-man/types.ts b/packages/js/plugins/logger/src/query/w3-man/types.ts new file mode 100644 index 0000000000..b8a849a41b --- /dev/null +++ b/packages/js/plugins/logger/src/query/w3-man/types.ts @@ -0,0 +1,64 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +// @ts-ignore +import * as Types from "./"; + +// @ts-ignore +import { Client, InvokeApiResult } from "@web3api/core-js"; + +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; + +/// Imported Enums START /// + +/* URI: "ens/logger.core.web3api.eth" */ +export enum Logger_LogLevelEnum { + DEBUG, + INFO, + WARN, + ERROR, +} + +export type Logger_LogLevelString = "DEBUG" | "INFO" | "WARN" | "ERROR"; + +export type Logger_LogLevel = Logger_LogLevelEnum | Logger_LogLevelString; + +/// Imported Enums END /// + +/// Imported Queries START /// + +/* URI: "ens/logger.core.web3api.eth" */ +interface Logger_Query_Input_log extends Record { + level: Types.Logger_LogLevel; + message: string; +} + +/* URI: "ens/logger.core.web3api.eth" */ +export const Logger_Query = { + log: async ( + input: Logger_Query_Input_log, + client: Client + ): Promise> => { + return client.invoke({ + uri: "ens/logger.core.web3api.eth", + module: "query", + method: "log", + input, + }); + }, +}; + +/// Imported Queries END /// diff --git a/packages/js/plugins/logger/src/resolvers.ts b/packages/js/plugins/logger/src/resolvers.ts deleted file mode 100644 index d1b2aaa1f4..0000000000 --- a/packages/js/plugins/logger/src/resolvers.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { LoggerPlugin } from "."; -import { Query } from "./w3"; - -export const query = (plugin: LoggerPlugin): Query.Module => ({ - log: (input: Query.Input_log) => { - return plugin.log(input.level, input.message); - }, -}); diff --git a/packages/js/plugins/logger/src/w3-man/index.ts b/packages/js/plugins/logger/src/w3-man/index.ts new file mode 100644 index 0000000000..b4849fdac4 --- /dev/null +++ b/packages/js/plugins/logger/src/w3-man/index.ts @@ -0,0 +1,3 @@ +export * from "./schema"; +export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/js/plugins/logger/src/w3-man/manifest.ts b/packages/js/plugins/logger/src/w3-man/manifest.ts new file mode 100644 index 0000000000..00f384f8a5 --- /dev/null +++ b/packages/js/plugins/logger/src/w3-man/manifest.ts @@ -0,0 +1,15 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +import { schema } from "./"; + +// @ts-ignore +import { PluginPackageManifest, Uri } from "@web3api/core-js"; + +export const manifest: PluginPackageManifest = { + schema, + implements: [new Uri("ens/logger.core.web3api.eth")], +}; diff --git a/packages/js/plugins/logger/src/w3-man/plugin.ts b/packages/js/plugins/logger/src/w3-man/plugin.ts new file mode 100644 index 0000000000..661dd3c6b3 --- /dev/null +++ b/packages/js/plugins/logger/src/w3-man/plugin.ts @@ -0,0 +1,41 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { Query, QueryConfig } from "../query"; +import { manifest } from "./manifest"; + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; + +export interface LoggerPluginConfigs { + query: QueryConfig; +} + +export class LoggerPlugin implements Plugin { + constructor(private _configs: LoggerPluginConfigs) {} + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + query: new Query(this._configs.query), + }; + } +} + +export const loggerPlugin: PluginFactory = ( + opts: LoggerPluginConfigs +) => { + return { + factory: () => new LoggerPlugin(opts), + manifest: manifest, + }; +}; + +export const plugin = loggerPlugin; diff --git a/packages/js/plugins/logger/src/w3-man/schema.ts b/packages/js/plugins/logger/src/w3-man/schema.ts new file mode 100644 index 0000000000..2bb3d56c07 --- /dev/null +++ b/packages/js/plugins/logger/src/w3-man/schema.ts @@ -0,0 +1,81 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export const schema = `### 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 implements Logger_Query @imports( + types: [ + "Logger_Query", + "Logger_LogLevel" + ] +) { + log( + level: Logger_LogLevel! + message: String! + ): Boolean! +} + +### Imported Queries START ### + +type Logger_Query @imported( + uri: "ens/logger.core.web3api.eth", + namespace: "Logger", + nativeType: "Query" +) { + log( + level: Logger_LogLevel! + message: String! + ): Boolean! +} + +### Imported Queries END ### + +### Imported Objects START ### + +enum Logger_LogLevel @imported( + uri: "ens/logger.core.web3api.eth", + namespace: "Logger", + nativeType: "LogLevel" +) { + DEBUG + INFO + WARN + ERROR +} + +### Imported Objects END ### +`; diff --git a/packages/js/plugins/logger/web3api.plugin.yaml b/packages/js/plugins/logger/web3api.plugin.yaml index 8d884901a3..e0cd1cd344 100644 --- a/packages/js/plugins/logger/web3api.plugin.yaml +++ b/packages/js/plugins/logger/web3api.plugin.yaml @@ -1,6 +1,10 @@ -format: 0.0.1-prealpha.1 +format: 0.0.1-prealpha.2 +name: Logger language: plugin/typescript -schema: ./schema.graphql +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts import_redirects: - uri: "ens/logger.core.web3api.eth" schema: ../../../core-interfaces/logger/src/query.graphql diff --git a/packages/js/plugins/sha3/package.json b/packages/js/plugins/sha3/package.json index 7c62b5bdea..1fa5dfedab 100644 --- a/packages/js/plugins/sha3/package.json +++ b/packages/js/plugins/sha3/package.json @@ -9,11 +9,12 @@ }, "main": "build/index.js", "files": [ - "build", - "schema.graphql" + "build" ], "scripts": { - "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "build": "rimraf ./build ./**/w3 ./*/**/w3 && tsc --project tsconfig.build.json", + "build:migrate": "npx w3 plugin codegen", + "build:bak": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", "codegen": "node ../../../../dependencies/node_modules/@web3api/cli/bin/w3 plugin codegen", "lint": "eslint --color -c ../../../../.eslintrc.js src/", "test": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/sha3/src/__tests__/index.test.ts b/packages/js/plugins/sha3/src/__tests__/index.test.ts index 81409f9be2..24efe28e47 100644 --- a/packages/js/plugins/sha3/src/__tests__/index.test.ts +++ b/packages/js/plugins/sha3/src/__tests__/index.test.ts @@ -23,7 +23,7 @@ describe("js-sha3 algorithms returned values match the plugin's", () => { plugins: [ { uri: "w3://ens/sha3.web3api.eth", - plugin: sha3Plugin(), + plugin: sha3Plugin({ query: {} }), }, ] }) diff --git a/packages/js/plugins/sha3/src/index.ts b/packages/js/plugins/sha3/src/index.ts index 0c77a29a48..a7af0fac7a 100644 --- a/packages/js/plugins/sha3/src/index.ts +++ b/packages/js/plugins/sha3/src/index.ts @@ -1,26 +1,3 @@ -import { manifest, Query } from "./w3"; -import { query } from "./resolvers"; +// TIP: All user-defined code lives in the module folders (./query, ./mutation) -import { Plugin, PluginPackageManifest, PluginPackage } from "@web3api/core-js"; - -export class SHA3Plugin extends Plugin { - public static manifest(): PluginPackageManifest { - return manifest; - } - - getModules(): { - query: Query.Module; - } { - return { - query: query(), - }; - } -} - -export const sha3Plugin = (): PluginPackage => { - return { - factory: () => new SHA3Plugin(), - manifest: manifest, - }; -}; -export const plugin = sha3Plugin; +export * from "./w3-man"; diff --git a/packages/js/plugins/sha3/src/resolvers.ts b/packages/js/plugins/sha3/src/query/index.ts similarity index 54% rename from packages/js/plugins/sha3/src/resolvers.ts rename to packages/js/plugins/sha3/src/query/index.ts index 79f00b12f1..80c2826ee7 100644 --- a/packages/js/plugins/sha3/src/resolvers.ts +++ b/packages/js/plugins/sha3/src/query/index.ts @@ -1,5 +1,22 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/naming-convention */ -import { Query } from "./w3"; +/* eslint-disable @typescript-eslint/no-empty-interface */ + +import { + Module, + Input_sha3_512, + Input_sha3_384, + Input_sha3_256, + Input_sha3_224, + Input_keccak_512, + Input_keccak_384, + Input_keccak_256, + Input_keccak_224, + Input_hex_keccak_256, + Input_buffer_keccak_256, + Input_shake_128, + Input_shake_256, +} from "./w3-man"; import { sha3_512, @@ -14,29 +31,38 @@ import { shake_256, } from "js-sha3"; -export const query = (): Query.Module => ({ - sha3_512: (input: Query.Input_sha3_512) => { +export interface QueryConfig extends Record {} + +export class Query extends Module { + public sha3_512(input: Input_sha3_512): string { return sha3_512(input.message); - }, - sha3_384: (input: Query.Input_sha3_384) => { + } + + public sha3_384(input: Input_sha3_384): string { return sha3_384(input.message); - }, - sha3_256: (input: Query.Input_sha3_256) => { + } + + public sha3_256(input: Input_sha3_256): string { return sha3_256(input.message); - }, - sha3_224: (input: Query.Input_sha3_224) => { + } + + public sha3_224(input: Input_sha3_224): string { return sha3_224(input.message); - }, - keccak_512: (input: Query.Input_keccak_512) => { + } + + public keccak_512(input: Input_keccak_512): string { return keccak_512(input.message); - }, - keccak_384: (input: Query.Input_keccak_384) => { + } + + public keccak_384(input: Input_keccak_384): string { return keccak_384(input.message); - }, - keccak_256: (input: Query.Input_keccak_256) => { + } + + public keccak_256(input: Input_keccak_256): string { return keccak_256(input.message); - }, - hex_keccak_256: (input: Query.Input_hex_keccak_256) => { + } + + public hex_keccak_256(input: Input_hex_keccak_256): string { // remove the leading 0x const hexString = input.message.replace(/^0x/, ""); @@ -66,17 +92,21 @@ export const query = (): Query.Module => ({ }); return keccak_256(new Uint8Array(integers)); - }, - buffer_keccak_256: (input: Query.Input_buffer_keccak_256) => { + } + + public buffer_keccak_256(input: Input_buffer_keccak_256): string { return keccak_256(input.message); - }, - keccak_224: (input: Query.Input_keccak_224) => { + } + + public keccak_224(input: Input_keccak_224): string { return keccak_224(input.message); - }, - shake_128: (input: Query.Input_shake_128) => { + } + + public shake_128(input: Input_shake_128): string { return shake_128(input.message, input.outputBits); - }, - shake_256: (input: Query.Input_shake_256) => { + } + + public shake_256(input: Input_shake_256): string { return shake_256(input.message, input.outputBits); - }, -}); + } +} diff --git a/packages/js/plugins/sha3/schema.graphql b/packages/js/plugins/sha3/src/query/schema.graphql similarity index 100% rename from packages/js/plugins/sha3/schema.graphql rename to packages/js/plugins/sha3/src/query/schema.graphql diff --git a/packages/js/plugins/sha3/src/query/w3-man/index.ts b/packages/js/plugins/sha3/src/query/w3-man/index.ts new file mode 100644 index 0000000000..6417838d60 --- /dev/null +++ b/packages/js/plugins/sha3/src/query/w3-man/index.ts @@ -0,0 +1,4 @@ +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/core-js"; diff --git a/packages/js/plugins/sha3/src/query/w3-man/module.ts b/packages/js/plugins/sha3/src/query/w3-man/module.ts new file mode 100644 index 0000000000..5fcba902ce --- /dev/null +++ b/packages/js/plugins/sha3/src/query/w3-man/module.ts @@ -0,0 +1,120 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as Types from "./types"; + +import { Client, PluginModule, MaybeAsync } from "@web3api/core-js"; + +export interface Input_sha3_512 extends Record { + message: Types.String; +} + +export interface Input_sha3_384 extends Record { + message: Types.String; +} + +export interface Input_sha3_256 extends Record { + message: Types.String; +} + +export interface Input_sha3_224 extends Record { + message: Types.String; +} + +export interface Input_keccak_512 extends Record { + message: Types.String; +} + +export interface Input_keccak_384 extends Record { + message: Types.String; +} + +export interface Input_keccak_256 extends Record { + message: Types.String; +} + +export interface Input_keccak_224 extends Record { + message: Types.String; +} + +export interface Input_hex_keccak_256 extends Record { + message: Types.String; +} + +export interface Input_buffer_keccak_256 extends Record { + message: Types.Bytes; +} + +export interface Input_shake_128 extends Record { + message: Types.String; + outputBits: Types.Int; +} + +export interface Input_shake_256 extends Record { + message: Types.String; + outputBits: Types.Int; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule { + abstract sha3_512( + input: Input_sha3_512, + client: Client + ): MaybeAsync; + + abstract sha3_384( + input: Input_sha3_384, + client: Client + ): MaybeAsync; + + abstract sha3_256( + input: Input_sha3_256, + client: Client + ): MaybeAsync; + + abstract sha3_224( + input: Input_sha3_224, + client: Client + ): MaybeAsync; + + abstract keccak_512( + input: Input_keccak_512, + client: Client + ): MaybeAsync; + + abstract keccak_384( + input: Input_keccak_384, + client: Client + ): MaybeAsync; + + abstract keccak_256( + input: Input_keccak_256, + client: Client + ): MaybeAsync; + + abstract keccak_224( + input: Input_keccak_224, + client: Client + ): MaybeAsync; + + abstract hex_keccak_256( + input: Input_hex_keccak_256, + client: Client + ): MaybeAsync; + + abstract buffer_keccak_256( + input: Input_buffer_keccak_256, + client: Client + ): MaybeAsync; + + abstract shake_128( + input: Input_shake_128, + client: Client + ): MaybeAsync; + + abstract shake_256( + input: Input_shake_256, + client: Client + ): MaybeAsync; +} diff --git a/packages/js/plugins/sha3/src/query/w3-man/types.ts b/packages/js/plugins/sha3/src/query/w3-man/types.ts new file mode 100644 index 0000000000..e6af7e5e03 --- /dev/null +++ b/packages/js/plugins/sha3/src/query/w3-man/types.ts @@ -0,0 +1,13 @@ +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; diff --git a/packages/js/plugins/sha3/src/w3-man/index.ts b/packages/js/plugins/sha3/src/w3-man/index.ts new file mode 100644 index 0000000000..b4849fdac4 --- /dev/null +++ b/packages/js/plugins/sha3/src/w3-man/index.ts @@ -0,0 +1,3 @@ +export * from "./schema"; +export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/js/plugins/sha3/src/w3-man/manifest.ts b/packages/js/plugins/sha3/src/w3-man/manifest.ts new file mode 100644 index 0000000000..41ca650b30 --- /dev/null +++ b/packages/js/plugins/sha3/src/w3-man/manifest.ts @@ -0,0 +1,13 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +/* eslint-disable @typescript-eslint/no-unused-vars */ + +import { schema } from "./"; + +import { PluginPackageManifest } from "@web3api/core-js"; + +export const manifest: PluginPackageManifest = { + schema, + implements: [], +}; diff --git a/packages/js/plugins/sha3/src/w3-man/plugin.ts b/packages/js/plugins/sha3/src/w3-man/plugin.ts new file mode 100644 index 0000000000..400d7218cb --- /dev/null +++ b/packages/js/plugins/sha3/src/w3-man/plugin.ts @@ -0,0 +1,41 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { Query, QueryConfig } from "../query"; +import { manifest } from "./manifest"; + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; + +export interface Sha3PluginConfigs { + query: QueryConfig; +} + +export class Sha3Plugin implements Plugin { + constructor(private _configs: Sha3PluginConfigs) {} + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + query: new Query(this._configs.query), + }; + } +} + +export const sha3Plugin: PluginFactory = ( + opts: Sha3PluginConfigs +) => { + return { + factory: () => new Sha3Plugin(opts), + manifest: manifest, + }; +}; + +export const plugin = sha3Plugin; diff --git a/packages/js/plugins/sha3/src/w3-man/schema.ts b/packages/js/plugins/sha3/src/w3-man/schema.ts new file mode 100644 index 0000000000..7f6e5733c9 --- /dev/null +++ b/packages/js/plugins/sha3/src/w3-man/schema.ts @@ -0,0 +1,95 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export const schema = `### 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 + +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 +### Web3API Header END ### + +type 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! +} + +### Imported Queries START ### + +### Imported Queries END ### + +### Imported Objects START ### + +### Imported Objects END ### +`; diff --git a/packages/js/plugins/sha3/web3api.plugin.yaml b/packages/js/plugins/sha3/web3api.plugin.yaml index b21359a846..768d6eb4a5 100644 --- a/packages/js/plugins/sha3/web3api.plugin.yaml +++ b/packages/js/plugins/sha3/web3api.plugin.yaml @@ -1,3 +1,7 @@ -format: 0.0.1-prealpha.1 +format: 0.0.1-prealpha.2 +name: Sha3 language: plugin/typescript -schema: ./schema.graphql +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts diff --git a/packages/js/plugins/uts46/package.json b/packages/js/plugins/uts46/package.json index 809587eeca..99ed607465 100644 --- a/packages/js/plugins/uts46/package.json +++ b/packages/js/plugins/uts46/package.json @@ -9,11 +9,12 @@ }, "main": "build/index.js", "files": [ - "build", - "schema.graphql" + "build" ], "scripts": { - "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "build": "rimraf ./build ./**/w3 ./*/**/w3 && tsc --project tsconfig.build.json", + "build:migrate": "npx w3 plugin codegen", + "build:bak": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", "codegen": "node ../../../../dependencies/node_modules/@web3api/cli/bin/w3 plugin codegen", "lint": "eslint --color -c ../../../../.eslintrc.js src/", "test": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/uts46/src/__tests__/index.test.ts b/packages/js/plugins/uts46/src/__tests__/index.test.ts index 8b8489486b..7ef984d0fa 100644 --- a/packages/js/plugins/uts46/src/__tests__/index.test.ts +++ b/packages/js/plugins/uts46/src/__tests__/index.test.ts @@ -12,7 +12,7 @@ describe("IDNA UTS #46", () => { plugins: [ { uri: "w3://ens/uts46.web3api.eth", - plugin: uts46Plugin(), + plugin: uts46Plugin({ query: {} }), }, ], }); diff --git a/packages/js/plugins/uts46/src/index.ts b/packages/js/plugins/uts46/src/index.ts index 43537face3..a7af0fac7a 100644 --- a/packages/js/plugins/uts46/src/index.ts +++ b/packages/js/plugins/uts46/src/index.ts @@ -1,26 +1,3 @@ -import { manifest, Query } from "./w3"; -import { query } from "./resolvers"; +// TIP: All user-defined code lives in the module folders (./query, ./mutation) -import { Plugin, PluginPackageManifest, PluginPackage } from "@web3api/core-js"; - -export class UTS46Plugin extends Plugin { - public static manifest(): PluginPackageManifest { - return manifest; - } - - getModules(): { - query: Query.Module; - } { - return { - query: query(), - }; - } -} - -export const uts46Plugin = (): PluginPackage => { - return { - factory: () => new UTS46Plugin(), - manifest: manifest, - }; -}; -export const plugin = uts46Plugin; +export * from "./w3-man"; diff --git a/packages/js/plugins/uts46/src/query/index.ts b/packages/js/plugins/uts46/src/query/index.ts new file mode 100644 index 0000000000..981a49419b --- /dev/null +++ b/packages/js/plugins/uts46/src/query/index.ts @@ -0,0 +1,27 @@ +/* eslint-disable @typescript-eslint/no-empty-interface */ +import { + Module, + Input_toAscii, + Input_toUnicode, + Input_convert, + ConvertResult, +} from "./w3-man"; + +// eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires +const uts46 = require("idna-uts46-hx/uts46bundle.js"); + +export interface QueryConfig extends Record {} + +export class Query extends Module { + public toAscii(input: Input_toAscii): string { + return uts46.toAscii(input.value); + } + + public toUnicode(input: Input_toUnicode): string { + return uts46.toUnicode(input.value); + } + + public convert(input: Input_convert): ConvertResult { + return uts46.convert(input.value); + } +} diff --git a/packages/js/plugins/uts46/schema.graphql b/packages/js/plugins/uts46/src/query/schema.graphql similarity index 100% rename from packages/js/plugins/uts46/schema.graphql rename to packages/js/plugins/uts46/src/query/schema.graphql diff --git a/packages/js/plugins/uts46/src/query/w3-man/index.ts b/packages/js/plugins/uts46/src/query/w3-man/index.ts new file mode 100644 index 0000000000..6417838d60 --- /dev/null +++ b/packages/js/plugins/uts46/src/query/w3-man/index.ts @@ -0,0 +1,4 @@ +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/core-js"; diff --git a/packages/js/plugins/uts46/src/query/w3-man/module.ts b/packages/js/plugins/uts46/src/query/w3-man/module.ts new file mode 100644 index 0000000000..146fb2127a --- /dev/null +++ b/packages/js/plugins/uts46/src/query/w3-man/module.ts @@ -0,0 +1,37 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as Types from "./types"; + +import { Client, PluginModule, MaybeAsync } from "@web3api/core-js"; + +export interface Input_toAscii extends Record { + value: Types.String; +} + +export interface Input_toUnicode extends Record { + value: Types.String; +} + +export interface Input_convert extends Record { + value: Types.String; +} + +export abstract class Module< + TConfig extends Record +> extends PluginModule { + abstract toAscii( + input: Input_toAscii, + client: Client + ): MaybeAsync; + + abstract toUnicode( + input: Input_toUnicode, + client: Client + ): MaybeAsync; + + abstract convert( + input: Input_convert, + client: Client + ): MaybeAsync; +} diff --git a/packages/js/plugins/uts46/src/query/w3-man/types.ts b/packages/js/plugins/uts46/src/query/w3-man/types.ts new file mode 100644 index 0000000000..048af33ac0 --- /dev/null +++ b/packages/js/plugins/uts46/src/query/w3-man/types.ts @@ -0,0 +1,21 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/naming-convention */ + +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; + +export interface ConvertResult { + IDN: string; + PC: string; +} diff --git a/packages/js/plugins/uts46/src/resolvers.ts b/packages/js/plugins/uts46/src/resolvers.ts deleted file mode 100644 index a9c02d4818..0000000000 --- a/packages/js/plugins/uts46/src/resolvers.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Query } from "./w3"; - -// eslint-disable-next-line @typescript-eslint/no-require-imports,@typescript-eslint/no-var-requires -const uts46 = require("idna-uts46-hx/uts46bundle.js"); - -export const query = (): Query.Module => ({ - toAscii: (input: Query.Input_toAscii) => { - return uts46.toAscii(input.value); - }, - toUnicode: (input: Query.Input_toUnicode) => { - return uts46.toUnicode(input.value); - }, - convert: (input: Query.Input_convert) => { - return uts46.convert(input.value); - }, -}); diff --git a/packages/js/plugins/uts46/src/w3-man/index.ts b/packages/js/plugins/uts46/src/w3-man/index.ts new file mode 100644 index 0000000000..b4849fdac4 --- /dev/null +++ b/packages/js/plugins/uts46/src/w3-man/index.ts @@ -0,0 +1,3 @@ +export * from "./schema"; +export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/js/plugins/uts46/src/w3-man/manifest.ts b/packages/js/plugins/uts46/src/w3-man/manifest.ts new file mode 100644 index 0000000000..db5cc12dc3 --- /dev/null +++ b/packages/js/plugins/uts46/src/w3-man/manifest.ts @@ -0,0 +1,9 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { schema } from "./"; + +import { PluginPackageManifest } from "@web3api/core-js"; + +export const manifest: PluginPackageManifest = { + schema, + implements: [], +}; diff --git a/packages/js/plugins/uts46/src/w3-man/plugin.ts b/packages/js/plugins/uts46/src/w3-man/plugin.ts new file mode 100644 index 0000000000..c9e06d8ae2 --- /dev/null +++ b/packages/js/plugins/uts46/src/w3-man/plugin.ts @@ -0,0 +1,41 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { Query, QueryConfig } from "../query"; +import { manifest } from "./manifest"; + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; + +export interface Uts46PluginConfigs { + query: QueryConfig; +} + +export class Uts46Plugin implements Plugin { + constructor(private _configs: Uts46PluginConfigs) {} + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + query: new Query(this._configs.query), + }; + } +} + +export const uts46Plugin: PluginFactory = ( + opts: Uts46PluginConfigs +) => { + return { + factory: () => new Uts46Plugin(opts), + manifest: manifest, + }; +}; + +export const plugin = uts46Plugin; diff --git a/packages/js/plugins/uts46/src/w3-man/schema.ts b/packages/js/plugins/uts46/src/w3-man/schema.ts new file mode 100644 index 0000000000..ba365c6f55 --- /dev/null +++ b/packages/js/plugins/uts46/src/w3-man/schema.ts @@ -0,0 +1,59 @@ +export const schema = `### 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 + +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 +### Web3API Header END ### + +type Query { + toAscii( + value: String! + ): String! + + toUnicode( + value: String! + ): String! + + convert( + value: String! + ): ConvertResult! +} + +type ConvertResult { + IDN: String! + PC: String! +} + +### Imported Queries START ### + +### Imported Queries END ### + +### Imported Objects START ### + +### Imported Objects END ### +`; diff --git a/packages/js/plugins/uts46/web3api.plugin.yaml b/packages/js/plugins/uts46/web3api.plugin.yaml index b21359a846..a796edda33 100644 --- a/packages/js/plugins/uts46/web3api.plugin.yaml +++ b/packages/js/plugins/uts46/web3api.plugin.yaml @@ -1,3 +1,7 @@ -format: 0.0.1-prealpha.1 +format: 0.0.1-prealpha.2 +name: Uts46 language: plugin/typescript -schema: ./schema.graphql +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts \ No newline at end of file diff --git a/packages/js/react/src/__tests__/plugins.ts b/packages/js/react/src/__tests__/plugins.ts index 25cad56bdf..3952f7bf05 100644 --- a/packages/js/react/src/__tests__/plugins.ts +++ b/packages/js/react/src/__tests__/plugins.ts @@ -30,8 +30,10 @@ export function createPlugins( { uri: "w3://ens/ens.web3api.eth", plugin: ensPlugin({ - addresses: { - testnet: ensAddress, + query: { + addresses: { + testnet: ensAddress, + }, }, }), }, diff --git a/packages/js/test-env/package.json b/packages/js/test-env/package.json index 690734fe89..2ac12cb8c6 100644 --- a/packages/js/test-env/package.json +++ b/packages/js/test-env/package.json @@ -16,6 +16,7 @@ "lint": "eslint --color -c ../../../.eslintrc.js src/" }, "dependencies": { + "@web3api/core-js": "^0.0.1-prealpha.71", "axios": "0.21.2", "spawn-command": "0.0.2-1" }, diff --git a/packages/js/test-env/src/generate-name.ts b/packages/js/test-env/src/generate-name.ts new file mode 100644 index 0000000000..91d7c012cb --- /dev/null +++ b/packages/js/test-env/src/generate-name.ts @@ -0,0 +1,2865 @@ +const getRandomInt = (min: number, max: number) => { + return Math.floor(Math.random() * (max - min)) + min; +}; + +export const generateName = (): string => { + const name1 = [ + "abandoned", + "able", + "absolute", + "adorable", + "adventurous", + "academic", + "acceptable", + "acclaimed", + "accomplished", + "accurate", + "aching", + "acidic", + "acrobatic", + "active", + "actual", + "adept", + "admirable", + "admired", + "adolescent", + "adorable", + "adored", + "advanced", + "afraid", + "affectionate", + "aged", + "aggravating", + "aggressive", + "agile", + "agitated", + "agonizing", + "agreeable", + "ajar", + "alarmed", + "alarming", + "alert", + "alienated", + "alive", + "all", + "altruistic", + "amazing", + "ambitious", + "ample", + "amused", + "amusing", + "anchored", + "ancient", + "angelic", + "angry", + "anguished", + "animated", + "annual", + "another", + "antique", + "anxious", + "any", + "apprehensive", + "appropriate", + "apt", + "arctic", + "arid", + "aromatic", + "artistic", + "ashamed", + "assured", + "astonishing", + "athletic", + "attached", + "attentive", + "attractive", + "austere", + "authentic", + "authorized", + "automatic", + "avaricious", + "average", + "aware", + "awesome", + "awful", + "awkward", + "babyish", + "bad", + "back", + "baggy", + "bare", + "barren", + "basic", + "beautiful", + "belated", + "beloved", + "beneficial", + "better", + "best", + "bewitched", + "big", + "big-hearted", + "biodegradable", + "bite-sized", + "bitter", + "black", + "black-and-white", + "bland", + "blank", + "blaring", + "bleak", + "blind", + "blissful", + "blond", + "blue", + "blushing", + "bogus", + "boiling", + "bold", + "bony", + "boring", + "bossy", + "both", + "bouncy", + "bountiful", + "bowed", + "brave", + "breakable", + "brief", + "bright", + "brilliant", + "brisk", + "broken", + "bronze", + "brown", + "bruised", + "bubbly", + "bulky", + "bumpy", + "buoyant", + "burdensome", + "burly", + "bustling", + "busy", + "buttery", + "buzzing", + "calculating", + "calm", + "candid", + "canine", + "capital", + "carefree", + "careful", + "careless", + "caring", + "cautious", + "cavernous", + "celebrated", + "charming", + "cheap", + "cheerful", + "cheery", + "chief", + "chilly", + "chubby", + "circular", + "classic", + "clean", + "clear", + "clear-cut", + "clever", + "close", + "closed", + "cloudy", + "clueless", + "clumsy", + "cluttered", + "coarse", + "cold", + "colorful", + "colorless", + "colossal", + "comfortable", + "common", + "compassionate", + "competent", + "complete", + "complex", + "complicated", + "composed", + "concerned", + "concrete", + "confused", + "conscious", + "considerate", + "constant", + "content", + "conventional", + "cooked", + "cool", + "cooperative", + "coordinated", + "corny", + "corrupt", + "costly", + "courageous", + "courteous", + "crafty", + "crazy", + "creamy", + "creative", + "creepy", + "criminal", + "crisp", + "critical", + "crooked", + "crowded", + "cruel", + "crushing", + "cuddly", + "cultivated", + "cultured", + "cumbersome", + "curly", + "curvy", + "cute", + "cylindrical", + "damaged", + "damp", + "dangerous", + "dapper", + "daring", + "darling", + "dark", + "dazzling", + "dead", + "deadly", + "deafening", + "dear", + "dearest", + "decent", + "decimal", + "decisive", + "deep", + "defenseless", + "defensive", + "defiant", + "deficient", + "definite", + "definitive", + "delayed", + "delectable", + "delicious", + "delightful", + "delirious", + "demanding", + "dense", + "dental", + "dependable", + "dependent", + "descriptive", + "deserted", + "detailed", + "determined", + "devoted", + "different", + "difficult", + "digital", + "diligent", + "dim", + "dimpled", + "dimwitted", + "direct", + "disastrous", + "discrete", + "disfigured", + "disgusting", + "disloyal", + "dismal", + "distant", + "downright", + "dreary", + "dirty", + "disguised", + "dishonest", + "dismal", + "distant", + "distinct", + "distorted", + "dizzy", + "dopey", + "doting", + "double", + "downright", + "drab", + "drafty", + "dramatic", + "dreary", + "droopy", + "dry", + "dual", + "dull", + "dutiful", + "each", + "eager", + "earnest", + "early", + "easy", + "easy-going", + "ecstatic", + "edible", + "educated", + "elaborate", + "elastic", + "elated", + "elderly", + "electric", + "elegant", + "elementary", + "elliptical", + "embarrassed", + "embellished", + "eminent", + "emotional", + "empty", + "enchanted", + "enchanting", + "energetic", + "enlightened", + "enormous", + "enraged", + "entire", + "envious", + "equal", + "equatorial", + "essential", + "esteemed", + "ethical", + "euphoric", + "even", + "evergreen", + "everlasting", + "every", + "evil", + "exalted", + "excellent", + "exemplary", + "exhausted", + "excitable", + "excited", + "exciting", + "exotic", + "expensive", + "experienced", + "expert", + "extraneous", + "extroverted", + "extra-large", + "extra-small", + "fabulous", + "failing", + "faint", + "fair", + "faithful", + "fake", + "false", + "familiar", + "famous", + "fancy", + "fantastic", + "far", + "faraway", + "far-flung", + "far-off", + "fast", + "fat", + "fatal", + "fatherly", + "favorable", + "favorite", + "fearful", + "fearless", + "feisty", + "feline", + "female", + "feminine", + "few", + "fickle", + "filthy", + "fine", + "finished", + "firm", + "first", + "firsthand", + "fitting", + "fixed", + "flaky", + "flamboyant", + "flashy", + "flat", + "flawed", + "flawless", + "flickering", + "flimsy", + "flippant", + "flowery", + "fluffy", + "fluid", + "flustered", + "focused", + "fond", + "foolhardy", + "foolish", + "forceful", + "forked", + "formal", + "forsaken", + "forthright", + "fortunate", + "fragrant", + "frail", + "frank", + "frayed", + "free", + "French", + "fresh", + "frequent", + "friendly", + "frightened", + "frightening", + "frigid", + "frilly", + "frizzy", + "frivolous", + "front", + "frosty", + "frozen", + "frugal", + "fruitful", + "full", + "fumbling", + "functional", + "funny", + "fussy", + "fuzzy", + "gargantuan", + "gaseous", + "general", + "generous", + "gentle", + "genuine", + "giant", + "giddy", + "gigantic", + "gifted", + "giving", + "glamorous", + "glaring", + "glass", + "gleaming", + "gleeful", + "glistening", + "glittering", + "gloomy", + "glorious", + "glossy", + "glum", + "golden", + "good", + "good-natured", + "gorgeous", + "graceful", + "gracious", + "grand", + "grandiose", + "granular", + "grateful", + "grave", + "gray", + "great", + "greedy", + "green", + "gregarious", + "grim", + "grimy", + "gripping", + "grizzled", + "gross", + "grotesque", + "grouchy", + "grounded", + "growing", + "growling", + "grown", + "grubby", + "gruesome", + "grumpy", + "guilty", + "gullible", + "gummy", + "hairy", + "half", + "handmade", + "handsome", + "handy", + "happy", + "happy-go-lucky", + "hard", + "hard-to-find", + "harmful", + "harmless", + "harmonious", + "harsh", + "hasty", + "hateful", + "haunting", + "healthy", + "heartfelt", + "hearty", + "heavenly", + "heavy", + "hefty", + "helpful", + "helpless", + "hidden", + "hideous", + "high", + "high-level", + "hilarious", + "hoarse", + "hollow", + "homely", + "honest", + "honorable", + "honored", + "hopeful", + "horrible", + "hospitable", + "hot", + "huge", + "humble", + "humiliating", + "humming", + "humongous", + "hungry", + "hurtful", + "husky", + "icky", + "icy", + "ideal", + "idealistic", + "identical", + "idle", + "idiotic", + "idolized", + "ignorant", + "ill", + "illegal", + "ill-fated", + "ill-informed", + "illiterate", + "illustrious", + "imaginary", + "imaginative", + "immaculate", + "immaterial", + "immediate", + "immense", + "impassioned", + "impeccable", + "impartial", + "imperfect", + "imperturbable", + "impish", + "impolite", + "important", + "impossible", + "impractical", + "impressionable", + "impressive", + "improbable", + "impure", + "inborn", + "incomparable", + "incompatible", + "incomplete", + "inconsequential", + "incredible", + "indelible", + "inexperienced", + "indolent", + "infamous", + "infantile", + "infatuated", + "inferior", + "infinite", + "informal", + "innocent", + "insecure", + "insidious", + "insignificant", + "insistent", + "instructive", + "insubstantial", + "intelligent", + "intent", + "intentional", + "interesting", + "internal", + "international", + "intrepid", + "ironclad", + "irresponsible", + "irritating", + "itchy", + "jaded", + "jagged", + "jam-packed", + "jaunty", + "jealous", + "jittery", + "joint", + "jolly", + "jovial", + "joyful", + "joyous", + "jubilant", + "judicious", + "juicy", + "jumbo", + "junior", + "jumpy", + "juvenile", + "kaleidoscopic", + "keen", + "key", + "kind", + "kindhearted", + "kindly", + "klutzy", + "knobby", + "knotty", + "knowledgeable", + "knowing", + "known", + "kooky", + "kosher", + "lame", + "lanky", + "large", + "last", + "lasting", + "late", + "lavish", + "lawful", + "lazy", + "leading", + "lean", + "leafy", + "left", + "legal", + "legitimate", + "light", + "lighthearted", + "likable", + "likely", + "limited", + "limp", + "limping", + "linear", + "lined", + "liquid", + "little", + "live", + "lively", + "livid", + "loathsome", + "lone", + "lonely", + "long", + "long-term", + "loose", + "lopsided", + "lost", + "loud", + "lovable", + "lovely", + "loving", + "low", + "loyal", + "lucky", + "lumbering", + "luminous", + "lumpy", + "lustrous", + "luxurious", + "mad", + "made-up", + "magnificent", + "majestic", + "major", + "male", + "mammoth", + "married", + "marvelous", + "masculine", + "massive", + "mature", + "meager", + "mealy", + "mean", + "measly", + "meaty", + "medical", + "mediocre", + "medium", + "meek", + "mellow", + "melodic", + "memorable", + "menacing", + "merry", + "messy", + "metallic", + "mild", + "milky", + "mindless", + "miniature", + "minor", + "minty", + "miserable", + "miserly", + "misguided", + "misty", + "mixed", + "modern", + "modest", + "moist", + "monstrous", + "monthly", + "monumental", + "moral", + "mortified", + "motherly", + "motionless", + "mountainous", + "muddy", + "muffled", + "multicolored", + "mundane", + "murky", + "mushy", + "musty", + "muted", + "mysterious", + "naive", + "narrow", + "nasty", + "natural", + "naughty", + "nautical", + "near", + "neat", + "necessary", + "needy", + "negative", + "neglected", + "negligible", + "neighboring", + "nervous", + "new", + "next", + "nice", + "nifty", + "nimble", + "nippy", + "nocturnal", + "noisy", + "nonstop", + "normal", + "notable", + "noted", + "noteworthy", + "novel", + "noxious", + "numb", + "nutritious", + "nutty", + "obedient", + "obese", + "oblong", + "oily", + "oblong", + "obvious", + "occasional", + "odd", + "oddball", + "offbeat", + "offensive", + "official", + "old", + "old-fashioned", + "only", + "open", + "optimal", + "optimistic", + "opulent", + "orange", + "orderly", + "organic", + "ornate", + "ornery", + "ordinary", + "original", + "other", + "our", + "outlying", + "outgoing", + "outlandish", + "outrageous", + "outstanding", + "oval", + "overcooked", + "overdue", + "overjoyed", + "overlooked", + "palatable", + "pale", + "paltry", + "parallel", + "parched", + "partial", + "passionate", + "past", + "pastel", + "peaceful", + "peppery", + "perfect", + "perfumed", + "periodic", + "perky", + "personal", + "pertinent", + "pesky", + "pessimistic", + "petty", + "phony", + "physical", + "piercing", + "pink", + "pitiful", + "plain", + "plaintive", + "plastic", + "playful", + "pleasant", + "pleased", + "pleasing", + "plump", + "plush", + "polished", + "polite", + "political", + "pointed", + "pointless", + "poised", + "poor", + "popular", + "portly", + "posh", + "positive", + "possible", + "potable", + "powerful", + "powerless", + "practical", + "precious", + "present", + "prestigious", + "pretty", + "precious", + "previous", + "pricey", + "prickly", + "primary", + "prime", + "pristine", + "private", + "prize", + "probable", + "productive", + "profitable", + "profuse", + "proper", + "proud", + "prudent", + "punctual", + "pungent", + "puny", + "pure", + "purple", + "pushy", + "putrid", + "puzzled", + "puzzling", + "quaint", + "qualified", + "quarrelsome", + "quarterly", + "queasy", + "querulous", + "questionable", + "quick", + "quick-witted", + "quiet", + "quintessential", + "quirky", + "quixotic", + "quizzical", + "radiant", + "ragged", + "rapid", + "rare", + "rash", + "raw", + "recent", + "reckless", + "rectangular", + "ready", + "real", + "realistic", + "reasonable", + "red", + "reflecting", + "regal", + "regular", + "reliable", + "relieved", + "remarkable", + "remorseful", + "remote", + "repentant", + "required", + "respectful", + "responsible", + "repulsive", + "revolving", + "rewarding", + "rich", + "rigid", + "right", + "ringed", + "ripe", + "roasted", + "robust", + "rosy", + "rotating", + "rotten", + "rough", + "round", + "rowdy", + "royal", + "rubbery", + "rundown", + "ruddy", + "rude", + "runny", + "rural", + "rusty", + "sad", + "safe", + "salty", + "same", + "sandy", + "sane", + "sarcastic", + "sardonic", + "satisfied", + "scaly", + "scarce", + "scared", + "scary", + "scented", + "scholarly", + "scientific", + "scornful", + "scratchy", + "scrawny", + "second", + "secondary", + "second-hand", + "secret", + "self-assured", + "self-reliant", + "selfish", + "sentimental", + "separate", + "serene", + "serious", + "serpentine", + "several", + "severe", + "shabby", + "shadowy", + "shady", + "shallow", + "shameful", + "shameless", + "sharp", + "shimmering", + "shiny", + "shocked", + "shocking", + "shoddy", + "short", + "short-term", + "showy", + "shrill", + "shy", + "sick", + "silent", + "silky", + "silly", + "silver", + "similar", + "simple", + "simplistic", + "sinful", + "single", + "sizzling", + "skeletal", + "skinny", + "sleepy", + "slight", + "slim", + "slimy", + "slippery", + "slow", + "slushy", + "small", + "smart", + "smoggy", + "smooth", + "smug", + "snappy", + "snarling", + "sneaky", + "sniveling", + "snoopy", + "sociable", + "soft", + "soggy", + "solid", + "somber", + "some", + "spherical", + "sophisticated", + "sore", + "sorrowful", + "soulful", + "soupy", + "sour", + "Spanish", + "sparkling", + "sparse", + "specific", + "spectacular", + "speedy", + "spicy", + "spiffy", + "spirited", + "spiteful", + "splendid", + "spotless", + "spotted", + "spry", + "square", + "squeaky", + "squiggly", + "stable", + "staid", + "stained", + "stale", + "standard", + "starchy", + "stark", + "starry", + "steep", + "sticky", + "stiff", + "stimulating", + "stingy", + "stormy", + "straight", + "strange", + "steel", + "strict", + "strident", + "striking", + "striped", + "strong", + "studious", + "stunning", + "stupendous", + "stupid", + "sturdy", + "stylish", + "subdued", + "submissive", + "substantial", + "subtle", + "suburban", + "sudden", + "sugary", + "sunny", + "super", + "superb", + "superficial", + "superior", + "supportive", + "sure-footed", + "surprised", + "suspicious", + "svelte", + "sweaty", + "sweet", + "sweltering", + "swift", + "sympathetic", + "tall", + "talkative", + "tame", + "tan", + "tangible", + "tart", + "tasty", + "tattered", + "taut", + "tedious", + "teeming", + "tempting", + "tender", + "tense", + "tepid", + "terrible", + "terrific", + "testy", + "thankful", + "that", + "these", + "thick", + "thin", + "third", + "thirsty", + "this", + "thorough", + "thorny", + "those", + "thoughtful", + "threadbare", + "thrifty", + "thunderous", + "tidy", + "tight", + "timely", + "tinted", + "tiny", + "tired", + "torn", + "total", + "tough", + "traumatic", + "treasured", + "tremendous", + "tragic", + "trained", + "tremendous", + "triangular", + "tricky", + "trifling", + "trim", + "trivial", + "troubled", + "true", + "trusting", + "trustworthy", + "trusty", + "truthful", + "tubby", + "turbulent", + "twin", + "ugly", + "ultimate", + "unacceptable", + "unaware", + "uncomfortable", + "uncommon", + "unconscious", + "understated", + "unequaled", + "uneven", + "unfinished", + "unfit", + "unfolded", + "unfortunate", + "unhappy", + "unhealthy", + "uniform", + "unimportant", + "unique", + "united", + "unkempt", + "unknown", + "unlawful", + "unlined", + "unlucky", + "unnatural", + "unpleasant", + "unrealistic", + "unripe", + "unruly", + "unselfish", + "unsightly", + "unsteady", + "unsung", + "untidy", + "untimely", + "untried", + "untrue", + "unused", + "unusual", + "unwelcome", + "unwieldy", + "unwilling", + "unwitting", + "unwritten", + "upbeat", + "upright", + "upset", + "urban", + "usable", + "used", + "useful", + "useless", + "utilized", + "utter", + "vacant", + "vague", + "vain", + "valid", + "valuable", + "vapid", + "variable", + "vast", + "velvety", + "venerated", + "vengeful", + "verifiable", + "vibrant", + "vicious", + "victorious", + "vigilant", + "vigorous", + "villainous", + "violet", + "violent", + "virtual", + "virtuous", + "visible", + "vital", + "vivacious", + "vivid", + "voluminous", + "wan", + "warlike", + "warm", + "warmhearted", + "warped", + "wary", + "wasteful", + "watchful", + "waterlogged", + "watery", + "wavy", + "wealthy", + "weak", + "weary", + "webbed", + "wee", + "weekly", + "weepy", + "weighty", + "weird", + "welcome", + "well-documented", + "well-groomed", + "well-informed", + "well-lit", + "well-made", + "well-off", + "well-to-do", + "well-worn", + "wet", + "which", + "whimsical", + "whirlwind", + "whispered", + "white", + "whole", + "whopping", + "wicked", + "wide", + "wide-eyed", + "wiggly", + "wild", + "willing", + "wilted", + "winding", + "windy", + "winged", + "wiry", + "wise", + "witty", + "wobbly", + "woeful", + "wonderful", + "wooden", + "woozy", + "wordy", + "worldly", + "worn", + "worried", + "worrisome", + "worse", + "worst", + "worthless", + "worthwhile", + "worthy", + "wrathful", + "wretched", + "writhing", + "wrong", + "wry", + "yawning", + "yearly", + "yellow", + "yellowish", + "young", + "youthful", + "yummy", + "zany", + "zealous", + "zesty", + "zigzag", + "rocky", + ]; + + const name2 = [ + "people", + "history", + "way", + "art", + "world", + "information", + "map", + "family", + "government", + "health", + "system", + "computer", + "meat", + "year", + "thanks", + "music", + "person", + "reading", + "method", + "data", + "food", + "understanding", + "theory", + "law", + "bird", + "literature", + "problem", + "software", + "control", + "knowledge", + "power", + "ability", + "economics", + "love", + "internet", + "television", + "science", + "library", + "nature", + "fact", + "product", + "idea", + "temperature", + "investment", + "area", + "society", + "activity", + "story", + "industry", + "media", + "thing", + "oven", + "community", + "definition", + "safety", + "quality", + "development", + "language", + "management", + "player", + "variety", + "video", + "week", + "security", + "country", + "exam", + "movie", + "organization", + "equipment", + "physics", + "analysis", + "policy", + "series", + "thought", + "basis", + "boyfriend", + "direction", + "strategy", + "technology", + "army", + "camera", + "freedom", + "paper", + "environment", + "child", + "instance", + "month", + "truth", + "marketing", + "university", + "writing", + "article", + "department", + "difference", + "goal", + "news", + "audience", + "fishing", + "growth", + "income", + "marriage", + "user", + "combination", + "failure", + "meaning", + "medicine", + "philosophy", + "teacher", + "communication", + "night", + "chemistry", + "disease", + "disk", + "energy", + "nation", + "road", + "role", + "soup", + "advertising", + "location", + "success", + "addition", + "apartment", + "education", + "math", + "moment", + "painting", + "politics", + "attention", + "decision", + "event", + "property", + "shopping", + "student", + "wood", + "competition", + "distribution", + "entertainment", + "office", + "population", + "president", + "unit", + "category", + "cigarette", + "context", + "introduction", + "opportunity", + "performance", + "driver", + "flight", + "length", + "magazine", + "newspaper", + "relationship", + "teaching", + "cell", + "dealer", + "debate", + "finding", + "lake", + "member", + "message", + "phone", + "scene", + "appearance", + "association", + "concept", + "customer", + "death", + "discussion", + "housing", + "inflation", + "insurance", + "mood", + "woman", + "advice", + "blood", + "effort", + "expression", + "importance", + "opinion", + "payment", + "reality", + "responsibility", + "situation", + "skill", + "statement", + "wealth", + "application", + "city", + "county", + "depth", + "estate", + "foundation", + "grandmother", + "heart", + "perspective", + "photo", + "recipe", + "studio", + "topic", + "collection", + "depression", + "imagination", + "passion", + "percentage", + "resource", + "setting", + "ad", + "agency", + "college", + "connection", + "criticism", + "debt", + "description", + "memory", + "patience", + "secretary", + "solution", + "administration", + "aspect", + "attitude", + "director", + "personality", + "psychology", + "recommendation", + "response", + "selection", + "storage", + "version", + "alcohol", + "argument", + "complaint", + "contract", + "emphasis", + "highway", + "loss", + "membership", + "possession", + "preparation", + "steak", + "union", + "agreement", + "cancer", + "currency", + "employment", + "engineering", + "entry", + "interaction", + "limit", + "mixture", + "preference", + "region", + "republic", + "seat", + "tradition", + "virus", + "actor", + "classroom", + "delivery", + "device", + "difficulty", + "drama", + "election", + "engine", + "football", + "guidance", + "hotel", + "match", + "owner", + "priority", + "protection", + "suggestion", + "tension", + "variation", + "anxiety", + "atmosphere", + "awareness", + "bread", + "climate", + "comparison", + "confusion", + "construction", + "elevator", + "emotion", + "employee", + "employer", + "guest", + "height", + "leadership", + "mall", + "manager", + "operation", + "recording", + "respect", + "sample", + "transportation", + "boring", + "charity", + "cousin", + "disaster", + "editor", + "efficiency", + "excitement", + "extent", + "feedback", + "guitar", + "homework", + "leader", + "mom", + "outcome", + "permission", + "presentation", + "promotion", + "reflection", + "refrigerator", + "resolution", + "revenue", + "session", + "singer", + "tennis", + "basket", + "bonus", + "cabinet", + "childhood", + "church", + "clothes", + "coffee", + "dinner", + "drawing", + "hair", + "hearing", + "initiative", + "judgment", + "lab", + "measurement", + "mode", + "mud", + "orange", + "poetry", + "police", + "possibility", + "procedure", + "queen", + "ratio", + "relation", + "restaurant", + "satisfaction", + "sector", + "signature", + "significance", + "song", + "tooth", + "town", + "vehicle", + "volume", + "wife", + "accident", + "airport", + "appointment", + "arrival", + "assumption", + "baseball", + "chapter", + "committee", + "conversation", + "database", + "enthusiasm", + "error", + "explanation", + "farmer", + "gate", + "girl", + "hall", + "historian", + "hospital", + "injury", + "instruction", + "maintenance", + "manufacturer", + "meal", + "perception", + "pie", + "poem", + "presence", + "proposal", + "reception", + "replacement", + "revolution", + "river", + "son", + "speech", + "tea", + "village", + "warning", + "winner", + "worker", + "writer", + "assistance", + "breath", + "buyer", + "chest", + "chocolate", + "conclusion", + "contribution", + "cookie", + "courage", + "desk", + "drawer", + "establishment", + "examination", + "garbage", + "grocery", + "honey", + "impression", + "improvement", + "independence", + "insect", + "inspection", + "inspector", + "king", + "ladder", + "menu", + "penalty", + "piano", + "potato", + "profession", + "professor", + "quantity", + "reaction", + "requirement", + "salad", + "sister", + "supermarket", + "tongue", + "weakness", + "wedding", + "affair", + "ambition", + "analyst", + "apple", + "assignment", + "assistant", + "bathroom", + "bedroom", + "beer", + "birthday", + "celebration", + "championship", + "cheek", + "client", + "consequence", + "departure", + "diamond", + "dirt", + "ear", + "fortune", + "friendship", + "funeral", + "gene", + "girlfriend", + "hat", + "indication", + "intention", + "lady", + "midnight", + "negotiation", + "obligation", + "passenger", + "pizza", + "platform", + "poet", + "pollution", + "recognition", + "reputation", + "shirt", + "speaker", + "stranger", + "surgery", + "sympathy", + "tale", + "throat", + "trainer", + "uncle", + "youth", + "time", + "work", + "film", + "water", + "money", + "example", + "while", + "business", + "study", + "game", + "life", + "form", + "air", + "day", + "place", + "number", + "part", + "field", + "fish", + "back", + "process", + "heat", + "hand", + "experience", + "job", + "book", + "end", + "point", + "type", + "home", + "economy", + "value", + "body", + "market", + "guide", + "interest", + "state", + "radio", + "course", + "company", + "price", + "size", + "card", + "list", + "mind", + "trade", + "line", + "care", + "group", + "risk", + "word", + "fat", + "force", + "key", + "light", + "training", + "name", + "school", + "top", + "amount", + "level", + "order", + "practice", + "research", + "sense", + "service", + "piece", + "web", + "boss", + "sport", + "fun", + "house", + "page", + "term", + "test", + "answer", + "sound", + "focus", + "matter", + "kind", + "soil", + "board", + "oil", + "picture", + "access", + "garden", + "range", + "rate", + "reason", + "future", + "site", + "demand", + "exercise", + "image", + "case", + "cause", + "coast", + "action", + "age", + "bad", + "boat", + "record", + "result", + "section", + "building", + "mouse", + "cash", + "class", + "period", + "plan", + "store", + "tax", + "side", + "subject", + "space", + "rule", + "stock", + "weather", + "chance", + "figure", + "man", + "model", + "source", + "beginning", + "earth", + "program", + "chicken", + "design", + "feature", + "head", + "material", + "purpose", + "question", + "rock", + "salt", + "act", + "birth", + "car", + "dog", + "object", + "scale", + "sun", + "note", + "profit", + "rent", + "speed", + "style", + "war", + "bank", + "craft", + "half", + "inside", + "outside", + "standard", + "bus", + "exchange", + "eye", + "fire", + "position", + "pressure", + "stress", + "advantage", + "benefit", + "box", + "frame", + "issue", + "step", + "cycle", + "face", + "item", + "metal", + "paint", + "review", + "room", + "screen", + "structure", + "view", + "account", + "ball", + "discipline", + "medium", + "share", + "balance", + "bit", + "black", + "bottom", + "choice", + "gift", + "impact", + "machine", + "shape", + "tool", + "wind", + "address", + "average", + "career", + "culture", + "morning", + "pot", + "sign", + "table", + "task", + "condition", + "contact", + "credit", + "egg", + "hope", + "ice", + "network", + "north", + "square", + "attempt", + "date", + "effect", + "link", + "post", + "star", + "voice", + "capital", + "challenge", + "friend", + "self", + "shot", + "brush", + "couple", + "exit", + "front", + "function", + "lack", + "living", + "plant", + "plastic", + "spot", + "summer", + "taste", + "theme", + "track", + "wing", + "brain", + "button", + "click", + "desire", + "foot", + "gas", + "influence", + "notice", + "rain", + "wall", + "base", + "damage", + "distance", + "feeling", + "pair", + "savings", + "staff", + "sugar", + "target", + "text", + "animal", + "author", + "budget", + "discount", + "file", + "ground", + "lesson", + "minute", + "officer", + "phase", + "reference", + "register", + "sky", + "stage", + "stick", + "title", + "trouble", + "bowl", + "bridge", + "campaign", + "character", + "club", + "edge", + "evidence", + "fan", + "letter", + "lock", + "maximum", + "novel", + "option", + "pack", + "park", + "quarter", + "skin", + "sort", + "weight", + "baby", + "background", + "carry", + "dish", + "factor", + "fruit", + "glass", + "joint", + "master", + "muscle", + "red", + "strength", + "traffic", + "trip", + "vegetable", + "appeal", + "chart", + "gear", + "ideal", + "kitchen", + "land", + "log", + "mother", + "net", + "party", + "principle", + "relative", + "sale", + "season", + "signal", + "spirit", + "street", + "tree", + "wave", + "belt", + "bench", + "commission", + "copy", + "drop", + "minimum", + "path", + "progress", + "project", + "sea", + "south", + "status", + "stuff", + "ticket", + "tour", + "angle", + "blue", + "breakfast", + "confidence", + "daughter", + "degree", + "doctor", + "dot", + "dream", + "duty", + "essay", + "father", + "fee", + "finance", + "hour", + "juice", + "luck", + "milk", + "mouth", + "peace", + "pipe", + "stable", + "storm", + "substance", + "team", + "trick", + "afternoon", + "bat", + "beach", + "blank", + "catch", + "chain", + "consideration", + "cream", + "crew", + "detail", + "gold", + "interview", + "kid", + "mark", + "mission", + "pain", + "pleasure", + "score", + "screw", + "sex", + "shop", + "shower", + "suit", + "tone", + "window", + "agent", + "band", + "bath", + "block", + "bone", + "calendar", + "candidate", + "cap", + "coat", + "contest", + "corner", + "court", + "cup", + "district", + "door", + "east", + "finger", + "garage", + "guarantee", + "hole", + "hook", + "implement", + "layer", + "lecture", + "lie", + "manner", + "meeting", + "nose", + "parking", + "partner", + "profile", + "rice", + "routine", + "schedule", + "swimming", + "telephone", + "tip", + "winter", + "airline", + "bag", + "battle", + "bed", + "bill", + "bother", + "cake", + "code", + "curve", + "designer", + "dimension", + "dress", + "ease", + "emergency", + "evening", + "extension", + "farm", + "fight", + "gap", + "grade", + "holiday", + "horror", + "horse", + "host", + "husband", + "loan", + "mistake", + "mountain", + "nail", + "noise", + "occasion", + "package", + "patient", + "pause", + "phrase", + "proof", + "race", + "relief", + "sand", + "sentence", + "shoulder", + "smoke", + "stomach", + "string", + "tourist", + "towel", + "vacation", + "west", + "wheel", + "wine", + "arm", + "aside", + "associate", + "bet", + "blow", + "border", + "branch", + "breast", + "brother", + "buddy", + "bunch", + "chip", + "coach", + "cross", + "document", + "draft", + "dust", + "expert", + "floor", + "god", + "golf", + "habit", + "iron", + "judge", + "knife", + "landscape", + "league", + "mail", + "mess", + "native", + "opening", + "parent", + "pattern", + "pin", + "pool", + "pound", + "request", + "salary", + "shame", + "shelter", + "shoe", + "silver", + "tackle", + "tank", + "trust", + "assist", + "bake", + "bar", + "bell", + "bike", + "blame", + "boy", + "brick", + "chair", + "closet", + "clue", + "collar", + "comment", + "conference", + "devil", + "diet", + "fear", + "fuel", + "glove", + "jacket", + "lunch", + "monitor", + "mortgage", + "nurse", + "pace", + "panic", + "peak", + "plane", + "reward", + "row", + "sandwich", + "shock", + "spite", + "spray", + "surprise", + "till", + "transition", + "weekend", + "welcome", + "yard", + "alarm", + "bend", + "bicycle", + "bite", + "blind", + "bottle", + "cable", + "candle", + "clerk", + "cloud", + "concert", + "counter", + "flower", + "grandfather", + "harm", + "knee", + "lawyer", + "leather", + "load", + "mirror", + "neck", + "pension", + "plate", + "purple", + "ruin", + "ship", + "skirt", + "slice", + "snow", + "specialist", + "stroke", + "switch", + "trash", + "tune", + "zone", + "anger", + "award", + "bid", + "bitter", + "boot", + "bug", + "camp", + "candy", + "carpet", + "cat", + "champion", + "channel", + "clock", + "comfort", + "cow", + "crack", + "engineer", + "entrance", + "fault", + "grass", + "guy", + "hell", + "highlight", + "incident", + "island", + "joke", + "jury", + "leg", + "lip", + "mate", + "motor", + "nerve", + "passage", + "pen", + "pride", + "priest", + "prize", + "promise", + "resident", + "resort", + "ring", + "roof", + "rope", + "sail", + "scheme", + "script", + "sock", + "station", + "toe", + "tower", + "truck", + "witness", + "can", + "will", + "other", + "use", + "make", + "good", + "look", + "help", + "go", + "great", + "being", + "still", + "public", + "read", + "keep", + "start", + "give", + "human", + "local", + "general", + "specific", + "long", + "play", + "feel", + "high", + "put", + "common", + "set", + "change", + "simple", + "past", + "big", + "possible", + "particular", + "major", + "personal", + "current", + "national", + "cut", + "natural", + "physical", + "show", + "try", + "check", + "second", + "call", + "move", + "pay", + "let", + "increase", + "single", + "individual", + "turn", + "ask", + "buy", + "guard", + "hold", + "main", + "offer", + "potential", + "professional", + "international", + "travel", + "cook", + "alternative", + "special", + "working", + "whole", + "dance", + "excuse", + "cold", + "commercial", + "low", + "purchase", + "deal", + "primary", + "worth", + "fall", + "necessary", + "positive", + "produce", + "search", + "present", + "spend", + "talk", + "creative", + "tell", + "cost", + "drive", + "green", + "support", + "glad", + "remove", + "return", + "run", + "complex", + "due", + "effective", + "middle", + "regular", + "reserve", + "independent", + "leave", + "original", + "reach", + "rest", + "serve", + "watch", + "beautiful", + "charge", + "active", + "break", + "negative", + "safe", + "stay", + "visit", + "visual", + "affect", + "cover", + "report", + "rise", + "walk", + "white", + "junior", + "pick", + "unique", + "classic", + "final", + "lift", + "mix", + "private", + "stop", + "teach", + "western", + "concern", + "familiar", + "fly", + "official", + "broad", + "comfortable", + "gain", + "rich", + "save", + "stand", + "young", + "heavy", + "lead", + "listen", + "valuable", + "worry", + "handle", + "leading", + "meet", + "release", + "sell", + "finish", + "normal", + "press", + "ride", + "secret", + "spread", + "spring", + "tough", + "wait", + "brown", + "deep", + "display", + "flow", + "hit", + "objective", + "shoot", + "touch", + "cancel", + "chemical", + "cry", + "dump", + "extreme", + "push", + "conflict", + "eat", + "fill", + "formal", + "jump", + "kick", + "opposite", + "pass", + "pitch", + "remote", + "total", + "treat", + "vast", + "abuse", + "beat", + "burn", + "deposit", + "print", + "raise", + "sleep", + "somewhere", + "advance", + "consist", + "dark", + "double", + "draw", + "equal", + "fix", + "hire", + "internal", + "join", + "kill", + "sensitive", + "tap", + "win", + "attack", + "claim", + "constant", + "drag", + "drink", + "guess", + "minor", + "pull", + "raw", + "soft", + "solid", + "wear", + "weird", + "wonder", + "annual", + "count", + "dead", + "doubt", + "feed", + "forever", + "impress", + "repeat", + "round", + "sing", + "slide", + "strip", + "wish", + "combine", + "command", + "dig", + "divide", + "equivalent", + "hang", + "hunt", + "initial", + "march", + "mention", + "spiritual", + "survey", + "tie", + "adult", + "brief", + "crazy", + "escape", + "gather", + "hate", + "prior", + "repair", + "rough", + "sad", + "scratch", + "sick", + "strike", + "employ", + "external", + "hurt", + "illegal", + "laugh", + "lay", + "mobile", + "nasty", + "ordinary", + "respond", + "royal", + "senior", + "split", + "strain", + "struggle", + "swim", + "train", + "upper", + "wash", + "yellow", + "convert", + "crash", + "dependent", + "fold", + "funny", + "grab", + "hide", + "miss", + "permit", + "quote", + "recover", + "resolve", + "roll", + "sink", + "slip", + "spare", + "suspect", + "sweet", + "swing", + "twist", + "upstairs", + "usual", + "abroad", + "brave", + "calm", + "concentrate", + "estimate", + "grand", + "male", + "mine", + "prompt", + "quiet", + "refuse", + "regret", + "reveal", + "rush", + "shake", + "shift", + "shine", + "steal", + "suck", + "surround", + "bear", + "brilliant", + "dare", + "dear", + "delay", + "drunk", + "female", + "hurry", + "inevitable", + "invite", + "kiss", + "neat", + "pop", + "punch", + "quit", + "reply", + "representative", + "resist", + "rip", + "rub", + "silly", + "smile", + "spell", + "stretch", + "stupid", + "tear", + "temporary", + "tomorrow", + "wake", + "wrap", + "yesterday", + "Thomas", + "Tom", + "Lieuwe", + ]; + + const name = `${name1[getRandomInt(0, name1.length + 1)]}-${ + name2[getRandomInt(0, name2.length + 1)] + }`; + return name; +}; diff --git a/packages/js/test-env/src/index.ts b/packages/js/test-env/src/index.ts index 40797b14e9..6534842010 100644 --- a/packages/js/test-env/src/index.ts +++ b/packages/js/test-env/src/index.ts @@ -1,3 +1,5 @@ +import { generateName } from "./generate-name"; + import path from "path"; import spawn from "spawn-command"; import axios from "axios"; @@ -174,2869 +176,3 @@ export async function buildAndDeployApi( ipfsCid: apiCid, }; } - -const getRandomInt = (min: number, max: number) => { - return Math.floor(Math.random() * (max - min)) + min; -}; - -export const generateName = (): string => { - const name1 = [ - "abandoned", - "able", - "absolute", - "adorable", - "adventurous", - "academic", - "acceptable", - "acclaimed", - "accomplished", - "accurate", - "aching", - "acidic", - "acrobatic", - "active", - "actual", - "adept", - "admirable", - "admired", - "adolescent", - "adorable", - "adored", - "advanced", - "afraid", - "affectionate", - "aged", - "aggravating", - "aggressive", - "agile", - "agitated", - "agonizing", - "agreeable", - "ajar", - "alarmed", - "alarming", - "alert", - "alienated", - "alive", - "all", - "altruistic", - "amazing", - "ambitious", - "ample", - "amused", - "amusing", - "anchored", - "ancient", - "angelic", - "angry", - "anguished", - "animated", - "annual", - "another", - "antique", - "anxious", - "any", - "apprehensive", - "appropriate", - "apt", - "arctic", - "arid", - "aromatic", - "artistic", - "ashamed", - "assured", - "astonishing", - "athletic", - "attached", - "attentive", - "attractive", - "austere", - "authentic", - "authorized", - "automatic", - "avaricious", - "average", - "aware", - "awesome", - "awful", - "awkward", - "babyish", - "bad", - "back", - "baggy", - "bare", - "barren", - "basic", - "beautiful", - "belated", - "beloved", - "beneficial", - "better", - "best", - "bewitched", - "big", - "big-hearted", - "biodegradable", - "bite-sized", - "bitter", - "black", - "black-and-white", - "bland", - "blank", - "blaring", - "bleak", - "blind", - "blissful", - "blond", - "blue", - "blushing", - "bogus", - "boiling", - "bold", - "bony", - "boring", - "bossy", - "both", - "bouncy", - "bountiful", - "bowed", - "brave", - "breakable", - "brief", - "bright", - "brilliant", - "brisk", - "broken", - "bronze", - "brown", - "bruised", - "bubbly", - "bulky", - "bumpy", - "buoyant", - "burdensome", - "burly", - "bustling", - "busy", - "buttery", - "buzzing", - "calculating", - "calm", - "candid", - "canine", - "capital", - "carefree", - "careful", - "careless", - "caring", - "cautious", - "cavernous", - "celebrated", - "charming", - "cheap", - "cheerful", - "cheery", - "chief", - "chilly", - "chubby", - "circular", - "classic", - "clean", - "clear", - "clear-cut", - "clever", - "close", - "closed", - "cloudy", - "clueless", - "clumsy", - "cluttered", - "coarse", - "cold", - "colorful", - "colorless", - "colossal", - "comfortable", - "common", - "compassionate", - "competent", - "complete", - "complex", - "complicated", - "composed", - "concerned", - "concrete", - "confused", - "conscious", - "considerate", - "constant", - "content", - "conventional", - "cooked", - "cool", - "cooperative", - "coordinated", - "corny", - "corrupt", - "costly", - "courageous", - "courteous", - "crafty", - "crazy", - "creamy", - "creative", - "creepy", - "criminal", - "crisp", - "critical", - "crooked", - "crowded", - "cruel", - "crushing", - "cuddly", - "cultivated", - "cultured", - "cumbersome", - "curly", - "curvy", - "cute", - "cylindrical", - "damaged", - "damp", - "dangerous", - "dapper", - "daring", - "darling", - "dark", - "dazzling", - "dead", - "deadly", - "deafening", - "dear", - "dearest", - "decent", - "decimal", - "decisive", - "deep", - "defenseless", - "defensive", - "defiant", - "deficient", - "definite", - "definitive", - "delayed", - "delectable", - "delicious", - "delightful", - "delirious", - "demanding", - "dense", - "dental", - "dependable", - "dependent", - "descriptive", - "deserted", - "detailed", - "determined", - "devoted", - "different", - "difficult", - "digital", - "diligent", - "dim", - "dimpled", - "dimwitted", - "direct", - "disastrous", - "discrete", - "disfigured", - "disgusting", - "disloyal", - "dismal", - "distant", - "downright", - "dreary", - "dirty", - "disguised", - "dishonest", - "dismal", - "distant", - "distinct", - "distorted", - "dizzy", - "dopey", - "doting", - "double", - "downright", - "drab", - "drafty", - "dramatic", - "dreary", - "droopy", - "dry", - "dual", - "dull", - "dutiful", - "each", - "eager", - "earnest", - "early", - "easy", - "easy-going", - "ecstatic", - "edible", - "educated", - "elaborate", - "elastic", - "elated", - "elderly", - "electric", - "elegant", - "elementary", - "elliptical", - "embarrassed", - "embellished", - "eminent", - "emotional", - "empty", - "enchanted", - "enchanting", - "energetic", - "enlightened", - "enormous", - "enraged", - "entire", - "envious", - "equal", - "equatorial", - "essential", - "esteemed", - "ethical", - "euphoric", - "even", - "evergreen", - "everlasting", - "every", - "evil", - "exalted", - "excellent", - "exemplary", - "exhausted", - "excitable", - "excited", - "exciting", - "exotic", - "expensive", - "experienced", - "expert", - "extraneous", - "extroverted", - "extra-large", - "extra-small", - "fabulous", - "failing", - "faint", - "fair", - "faithful", - "fake", - "false", - "familiar", - "famous", - "fancy", - "fantastic", - "far", - "faraway", - "far-flung", - "far-off", - "fast", - "fat", - "fatal", - "fatherly", - "favorable", - "favorite", - "fearful", - "fearless", - "feisty", - "feline", - "female", - "feminine", - "few", - "fickle", - "filthy", - "fine", - "finished", - "firm", - "first", - "firsthand", - "fitting", - "fixed", - "flaky", - "flamboyant", - "flashy", - "flat", - "flawed", - "flawless", - "flickering", - "flimsy", - "flippant", - "flowery", - "fluffy", - "fluid", - "flustered", - "focused", - "fond", - "foolhardy", - "foolish", - "forceful", - "forked", - "formal", - "forsaken", - "forthright", - "fortunate", - "fragrant", - "frail", - "frank", - "frayed", - "free", - "French", - "fresh", - "frequent", - "friendly", - "frightened", - "frightening", - "frigid", - "frilly", - "frizzy", - "frivolous", - "front", - "frosty", - "frozen", - "frugal", - "fruitful", - "full", - "fumbling", - "functional", - "funny", - "fussy", - "fuzzy", - "gargantuan", - "gaseous", - "general", - "generous", - "gentle", - "genuine", - "giant", - "giddy", - "gigantic", - "gifted", - "giving", - "glamorous", - "glaring", - "glass", - "gleaming", - "gleeful", - "glistening", - "glittering", - "gloomy", - "glorious", - "glossy", - "glum", - "golden", - "good", - "good-natured", - "gorgeous", - "graceful", - "gracious", - "grand", - "grandiose", - "granular", - "grateful", - "grave", - "gray", - "great", - "greedy", - "green", - "gregarious", - "grim", - "grimy", - "gripping", - "grizzled", - "gross", - "grotesque", - "grouchy", - "grounded", - "growing", - "growling", - "grown", - "grubby", - "gruesome", - "grumpy", - "guilty", - "gullible", - "gummy", - "hairy", - "half", - "handmade", - "handsome", - "handy", - "happy", - "happy-go-lucky", - "hard", - "hard-to-find", - "harmful", - "harmless", - "harmonious", - "harsh", - "hasty", - "hateful", - "haunting", - "healthy", - "heartfelt", - "hearty", - "heavenly", - "heavy", - "hefty", - "helpful", - "helpless", - "hidden", - "hideous", - "high", - "high-level", - "hilarious", - "hoarse", - "hollow", - "homely", - "honest", - "honorable", - "honored", - "hopeful", - "horrible", - "hospitable", - "hot", - "huge", - "humble", - "humiliating", - "humming", - "humongous", - "hungry", - "hurtful", - "husky", - "icky", - "icy", - "ideal", - "idealistic", - "identical", - "idle", - "idiotic", - "idolized", - "ignorant", - "ill", - "illegal", - "ill-fated", - "ill-informed", - "illiterate", - "illustrious", - "imaginary", - "imaginative", - "immaculate", - "immaterial", - "immediate", - "immense", - "impassioned", - "impeccable", - "impartial", - "imperfect", - "imperturbable", - "impish", - "impolite", - "important", - "impossible", - "impractical", - "impressionable", - "impressive", - "improbable", - "impure", - "inborn", - "incomparable", - "incompatible", - "incomplete", - "inconsequential", - "incredible", - "indelible", - "inexperienced", - "indolent", - "infamous", - "infantile", - "infatuated", - "inferior", - "infinite", - "informal", - "innocent", - "insecure", - "insidious", - "insignificant", - "insistent", - "instructive", - "insubstantial", - "intelligent", - "intent", - "intentional", - "interesting", - "internal", - "international", - "intrepid", - "ironclad", - "irresponsible", - "irritating", - "itchy", - "jaded", - "jagged", - "jam-packed", - "jaunty", - "jealous", - "jittery", - "joint", - "jolly", - "jovial", - "joyful", - "joyous", - "jubilant", - "judicious", - "juicy", - "jumbo", - "junior", - "jumpy", - "juvenile", - "kaleidoscopic", - "keen", - "key", - "kind", - "kindhearted", - "kindly", - "klutzy", - "knobby", - "knotty", - "knowledgeable", - "knowing", - "known", - "kooky", - "kosher", - "lame", - "lanky", - "large", - "last", - "lasting", - "late", - "lavish", - "lawful", - "lazy", - "leading", - "lean", - "leafy", - "left", - "legal", - "legitimate", - "light", - "lighthearted", - "likable", - "likely", - "limited", - "limp", - "limping", - "linear", - "lined", - "liquid", - "little", - "live", - "lively", - "livid", - "loathsome", - "lone", - "lonely", - "long", - "long-term", - "loose", - "lopsided", - "lost", - "loud", - "lovable", - "lovely", - "loving", - "low", - "loyal", - "lucky", - "lumbering", - "luminous", - "lumpy", - "lustrous", - "luxurious", - "mad", - "made-up", - "magnificent", - "majestic", - "major", - "male", - "mammoth", - "married", - "marvelous", - "masculine", - "massive", - "mature", - "meager", - "mealy", - "mean", - "measly", - "meaty", - "medical", - "mediocre", - "medium", - "meek", - "mellow", - "melodic", - "memorable", - "menacing", - "merry", - "messy", - "metallic", - "mild", - "milky", - "mindless", - "miniature", - "minor", - "minty", - "miserable", - "miserly", - "misguided", - "misty", - "mixed", - "modern", - "modest", - "moist", - "monstrous", - "monthly", - "monumental", - "moral", - "mortified", - "motherly", - "motionless", - "mountainous", - "muddy", - "muffled", - "multicolored", - "mundane", - "murky", - "mushy", - "musty", - "muted", - "mysterious", - "naive", - "narrow", - "nasty", - "natural", - "naughty", - "nautical", - "near", - "neat", - "necessary", - "needy", - "negative", - "neglected", - "negligible", - "neighboring", - "nervous", - "new", - "next", - "nice", - "nifty", - "nimble", - "nippy", - "nocturnal", - "noisy", - "nonstop", - "normal", - "notable", - "noted", - "noteworthy", - "novel", - "noxious", - "numb", - "nutritious", - "nutty", - "obedient", - "obese", - "oblong", - "oily", - "oblong", - "obvious", - "occasional", - "odd", - "oddball", - "offbeat", - "offensive", - "official", - "old", - "old-fashioned", - "only", - "open", - "optimal", - "optimistic", - "opulent", - "orange", - "orderly", - "organic", - "ornate", - "ornery", - "ordinary", - "original", - "other", - "our", - "outlying", - "outgoing", - "outlandish", - "outrageous", - "outstanding", - "oval", - "overcooked", - "overdue", - "overjoyed", - "overlooked", - "palatable", - "pale", - "paltry", - "parallel", - "parched", - "partial", - "passionate", - "past", - "pastel", - "peaceful", - "peppery", - "perfect", - "perfumed", - "periodic", - "perky", - "personal", - "pertinent", - "pesky", - "pessimistic", - "petty", - "phony", - "physical", - "piercing", - "pink", - "pitiful", - "plain", - "plaintive", - "plastic", - "playful", - "pleasant", - "pleased", - "pleasing", - "plump", - "plush", - "polished", - "polite", - "political", - "pointed", - "pointless", - "poised", - "poor", - "popular", - "portly", - "posh", - "positive", - "possible", - "potable", - "powerful", - "powerless", - "practical", - "precious", - "present", - "prestigious", - "pretty", - "precious", - "previous", - "pricey", - "prickly", - "primary", - "prime", - "pristine", - "private", - "prize", - "probable", - "productive", - "profitable", - "profuse", - "proper", - "proud", - "prudent", - "punctual", - "pungent", - "puny", - "pure", - "purple", - "pushy", - "putrid", - "puzzled", - "puzzling", - "quaint", - "qualified", - "quarrelsome", - "quarterly", - "queasy", - "querulous", - "questionable", - "quick", - "quick-witted", - "quiet", - "quintessential", - "quirky", - "quixotic", - "quizzical", - "radiant", - "ragged", - "rapid", - "rare", - "rash", - "raw", - "recent", - "reckless", - "rectangular", - "ready", - "real", - "realistic", - "reasonable", - "red", - "reflecting", - "regal", - "regular", - "reliable", - "relieved", - "remarkable", - "remorseful", - "remote", - "repentant", - "required", - "respectful", - "responsible", - "repulsive", - "revolving", - "rewarding", - "rich", - "rigid", - "right", - "ringed", - "ripe", - "roasted", - "robust", - "rosy", - "rotating", - "rotten", - "rough", - "round", - "rowdy", - "royal", - "rubbery", - "rundown", - "ruddy", - "rude", - "runny", - "rural", - "rusty", - "sad", - "safe", - "salty", - "same", - "sandy", - "sane", - "sarcastic", - "sardonic", - "satisfied", - "scaly", - "scarce", - "scared", - "scary", - "scented", - "scholarly", - "scientific", - "scornful", - "scratchy", - "scrawny", - "second", - "secondary", - "second-hand", - "secret", - "self-assured", - "self-reliant", - "selfish", - "sentimental", - "separate", - "serene", - "serious", - "serpentine", - "several", - "severe", - "shabby", - "shadowy", - "shady", - "shallow", - "shameful", - "shameless", - "sharp", - "shimmering", - "shiny", - "shocked", - "shocking", - "shoddy", - "short", - "short-term", - "showy", - "shrill", - "shy", - "sick", - "silent", - "silky", - "silly", - "silver", - "similar", - "simple", - "simplistic", - "sinful", - "single", - "sizzling", - "skeletal", - "skinny", - "sleepy", - "slight", - "slim", - "slimy", - "slippery", - "slow", - "slushy", - "small", - "smart", - "smoggy", - "smooth", - "smug", - "snappy", - "snarling", - "sneaky", - "sniveling", - "snoopy", - "sociable", - "soft", - "soggy", - "solid", - "somber", - "some", - "spherical", - "sophisticated", - "sore", - "sorrowful", - "soulful", - "soupy", - "sour", - "Spanish", - "sparkling", - "sparse", - "specific", - "spectacular", - "speedy", - "spicy", - "spiffy", - "spirited", - "spiteful", - "splendid", - "spotless", - "spotted", - "spry", - "square", - "squeaky", - "squiggly", - "stable", - "staid", - "stained", - "stale", - "standard", - "starchy", - "stark", - "starry", - "steep", - "sticky", - "stiff", - "stimulating", - "stingy", - "stormy", - "straight", - "strange", - "steel", - "strict", - "strident", - "striking", - "striped", - "strong", - "studious", - "stunning", - "stupendous", - "stupid", - "sturdy", - "stylish", - "subdued", - "submissive", - "substantial", - "subtle", - "suburban", - "sudden", - "sugary", - "sunny", - "super", - "superb", - "superficial", - "superior", - "supportive", - "sure-footed", - "surprised", - "suspicious", - "svelte", - "sweaty", - "sweet", - "sweltering", - "swift", - "sympathetic", - "tall", - "talkative", - "tame", - "tan", - "tangible", - "tart", - "tasty", - "tattered", - "taut", - "tedious", - "teeming", - "tempting", - "tender", - "tense", - "tepid", - "terrible", - "terrific", - "testy", - "thankful", - "that", - "these", - "thick", - "thin", - "third", - "thirsty", - "this", - "thorough", - "thorny", - "those", - "thoughtful", - "threadbare", - "thrifty", - "thunderous", - "tidy", - "tight", - "timely", - "tinted", - "tiny", - "tired", - "torn", - "total", - "tough", - "traumatic", - "treasured", - "tremendous", - "tragic", - "trained", - "tremendous", - "triangular", - "tricky", - "trifling", - "trim", - "trivial", - "troubled", - "true", - "trusting", - "trustworthy", - "trusty", - "truthful", - "tubby", - "turbulent", - "twin", - "ugly", - "ultimate", - "unacceptable", - "unaware", - "uncomfortable", - "uncommon", - "unconscious", - "understated", - "unequaled", - "uneven", - "unfinished", - "unfit", - "unfolded", - "unfortunate", - "unhappy", - "unhealthy", - "uniform", - "unimportant", - "unique", - "united", - "unkempt", - "unknown", - "unlawful", - "unlined", - "unlucky", - "unnatural", - "unpleasant", - "unrealistic", - "unripe", - "unruly", - "unselfish", - "unsightly", - "unsteady", - "unsung", - "untidy", - "untimely", - "untried", - "untrue", - "unused", - "unusual", - "unwelcome", - "unwieldy", - "unwilling", - "unwitting", - "unwritten", - "upbeat", - "upright", - "upset", - "urban", - "usable", - "used", - "useful", - "useless", - "utilized", - "utter", - "vacant", - "vague", - "vain", - "valid", - "valuable", - "vapid", - "variable", - "vast", - "velvety", - "venerated", - "vengeful", - "verifiable", - "vibrant", - "vicious", - "victorious", - "vigilant", - "vigorous", - "villainous", - "violet", - "violent", - "virtual", - "virtuous", - "visible", - "vital", - "vivacious", - "vivid", - "voluminous", - "wan", - "warlike", - "warm", - "warmhearted", - "warped", - "wary", - "wasteful", - "watchful", - "waterlogged", - "watery", - "wavy", - "wealthy", - "weak", - "weary", - "webbed", - "wee", - "weekly", - "weepy", - "weighty", - "weird", - "welcome", - "well-documented", - "well-groomed", - "well-informed", - "well-lit", - "well-made", - "well-off", - "well-to-do", - "well-worn", - "wet", - "which", - "whimsical", - "whirlwind", - "whispered", - "white", - "whole", - "whopping", - "wicked", - "wide", - "wide-eyed", - "wiggly", - "wild", - "willing", - "wilted", - "winding", - "windy", - "winged", - "wiry", - "wise", - "witty", - "wobbly", - "woeful", - "wonderful", - "wooden", - "woozy", - "wordy", - "worldly", - "worn", - "worried", - "worrisome", - "worse", - "worst", - "worthless", - "worthwhile", - "worthy", - "wrathful", - "wretched", - "writhing", - "wrong", - "wry", - "yawning", - "yearly", - "yellow", - "yellowish", - "young", - "youthful", - "yummy", - "zany", - "zealous", - "zesty", - "zigzag", - "rocky", - ]; - - const name2 = [ - "people", - "history", - "way", - "art", - "world", - "information", - "map", - "family", - "government", - "health", - "system", - "computer", - "meat", - "year", - "thanks", - "music", - "person", - "reading", - "method", - "data", - "food", - "understanding", - "theory", - "law", - "bird", - "literature", - "problem", - "software", - "control", - "knowledge", - "power", - "ability", - "economics", - "love", - "internet", - "television", - "science", - "library", - "nature", - "fact", - "product", - "idea", - "temperature", - "investment", - "area", - "society", - "activity", - "story", - "industry", - "media", - "thing", - "oven", - "community", - "definition", - "safety", - "quality", - "development", - "language", - "management", - "player", - "variety", - "video", - "week", - "security", - "country", - "exam", - "movie", - "organization", - "equipment", - "physics", - "analysis", - "policy", - "series", - "thought", - "basis", - "boyfriend", - "direction", - "strategy", - "technology", - "army", - "camera", - "freedom", - "paper", - "environment", - "child", - "instance", - "month", - "truth", - "marketing", - "university", - "writing", - "article", - "department", - "difference", - "goal", - "news", - "audience", - "fishing", - "growth", - "income", - "marriage", - "user", - "combination", - "failure", - "meaning", - "medicine", - "philosophy", - "teacher", - "communication", - "night", - "chemistry", - "disease", - "disk", - "energy", - "nation", - "road", - "role", - "soup", - "advertising", - "location", - "success", - "addition", - "apartment", - "education", - "math", - "moment", - "painting", - "politics", - "attention", - "decision", - "event", - "property", - "shopping", - "student", - "wood", - "competition", - "distribution", - "entertainment", - "office", - "population", - "president", - "unit", - "category", - "cigarette", - "context", - "introduction", - "opportunity", - "performance", - "driver", - "flight", - "length", - "magazine", - "newspaper", - "relationship", - "teaching", - "cell", - "dealer", - "debate", - "finding", - "lake", - "member", - "message", - "phone", - "scene", - "appearance", - "association", - "concept", - "customer", - "death", - "discussion", - "housing", - "inflation", - "insurance", - "mood", - "woman", - "advice", - "blood", - "effort", - "expression", - "importance", - "opinion", - "payment", - "reality", - "responsibility", - "situation", - "skill", - "statement", - "wealth", - "application", - "city", - "county", - "depth", - "estate", - "foundation", - "grandmother", - "heart", - "perspective", - "photo", - "recipe", - "studio", - "topic", - "collection", - "depression", - "imagination", - "passion", - "percentage", - "resource", - "setting", - "ad", - "agency", - "college", - "connection", - "criticism", - "debt", - "description", - "memory", - "patience", - "secretary", - "solution", - "administration", - "aspect", - "attitude", - "director", - "personality", - "psychology", - "recommendation", - "response", - "selection", - "storage", - "version", - "alcohol", - "argument", - "complaint", - "contract", - "emphasis", - "highway", - "loss", - "membership", - "possession", - "preparation", - "steak", - "union", - "agreement", - "cancer", - "currency", - "employment", - "engineering", - "entry", - "interaction", - "limit", - "mixture", - "preference", - "region", - "republic", - "seat", - "tradition", - "virus", - "actor", - "classroom", - "delivery", - "device", - "difficulty", - "drama", - "election", - "engine", - "football", - "guidance", - "hotel", - "match", - "owner", - "priority", - "protection", - "suggestion", - "tension", - "variation", - "anxiety", - "atmosphere", - "awareness", - "bread", - "climate", - "comparison", - "confusion", - "construction", - "elevator", - "emotion", - "employee", - "employer", - "guest", - "height", - "leadership", - "mall", - "manager", - "operation", - "recording", - "respect", - "sample", - "transportation", - "boring", - "charity", - "cousin", - "disaster", - "editor", - "efficiency", - "excitement", - "extent", - "feedback", - "guitar", - "homework", - "leader", - "mom", - "outcome", - "permission", - "presentation", - "promotion", - "reflection", - "refrigerator", - "resolution", - "revenue", - "session", - "singer", - "tennis", - "basket", - "bonus", - "cabinet", - "childhood", - "church", - "clothes", - "coffee", - "dinner", - "drawing", - "hair", - "hearing", - "initiative", - "judgment", - "lab", - "measurement", - "mode", - "mud", - "orange", - "poetry", - "police", - "possibility", - "procedure", - "queen", - "ratio", - "relation", - "restaurant", - "satisfaction", - "sector", - "signature", - "significance", - "song", - "tooth", - "town", - "vehicle", - "volume", - "wife", - "accident", - "airport", - "appointment", - "arrival", - "assumption", - "baseball", - "chapter", - "committee", - "conversation", - "database", - "enthusiasm", - "error", - "explanation", - "farmer", - "gate", - "girl", - "hall", - "historian", - "hospital", - "injury", - "instruction", - "maintenance", - "manufacturer", - "meal", - "perception", - "pie", - "poem", - "presence", - "proposal", - "reception", - "replacement", - "revolution", - "river", - "son", - "speech", - "tea", - "village", - "warning", - "winner", - "worker", - "writer", - "assistance", - "breath", - "buyer", - "chest", - "chocolate", - "conclusion", - "contribution", - "cookie", - "courage", - "desk", - "drawer", - "establishment", - "examination", - "garbage", - "grocery", - "honey", - "impression", - "improvement", - "independence", - "insect", - "inspection", - "inspector", - "king", - "ladder", - "menu", - "penalty", - "piano", - "potato", - "profession", - "professor", - "quantity", - "reaction", - "requirement", - "salad", - "sister", - "supermarket", - "tongue", - "weakness", - "wedding", - "affair", - "ambition", - "analyst", - "apple", - "assignment", - "assistant", - "bathroom", - "bedroom", - "beer", - "birthday", - "celebration", - "championship", - "cheek", - "client", - "consequence", - "departure", - "diamond", - "dirt", - "ear", - "fortune", - "friendship", - "funeral", - "gene", - "girlfriend", - "hat", - "indication", - "intention", - "lady", - "midnight", - "negotiation", - "obligation", - "passenger", - "pizza", - "platform", - "poet", - "pollution", - "recognition", - "reputation", - "shirt", - "speaker", - "stranger", - "surgery", - "sympathy", - "tale", - "throat", - "trainer", - "uncle", - "youth", - "time", - "work", - "film", - "water", - "money", - "example", - "while", - "business", - "study", - "game", - "life", - "form", - "air", - "day", - "place", - "number", - "part", - "field", - "fish", - "back", - "process", - "heat", - "hand", - "experience", - "job", - "book", - "end", - "point", - "type", - "home", - "economy", - "value", - "body", - "market", - "guide", - "interest", - "state", - "radio", - "course", - "company", - "price", - "size", - "card", - "list", - "mind", - "trade", - "line", - "care", - "group", - "risk", - "word", - "fat", - "force", - "key", - "light", - "training", - "name", - "school", - "top", - "amount", - "level", - "order", - "practice", - "research", - "sense", - "service", - "piece", - "web", - "boss", - "sport", - "fun", - "house", - "page", - "term", - "test", - "answer", - "sound", - "focus", - "matter", - "kind", - "soil", - "board", - "oil", - "picture", - "access", - "garden", - "range", - "rate", - "reason", - "future", - "site", - "demand", - "exercise", - "image", - "case", - "cause", - "coast", - "action", - "age", - "bad", - "boat", - "record", - "result", - "section", - "building", - "mouse", - "cash", - "class", - "period", - "plan", - "store", - "tax", - "side", - "subject", - "space", - "rule", - "stock", - "weather", - "chance", - "figure", - "man", - "model", - "source", - "beginning", - "earth", - "program", - "chicken", - "design", - "feature", - "head", - "material", - "purpose", - "question", - "rock", - "salt", - "act", - "birth", - "car", - "dog", - "object", - "scale", - "sun", - "note", - "profit", - "rent", - "speed", - "style", - "war", - "bank", - "craft", - "half", - "inside", - "outside", - "standard", - "bus", - "exchange", - "eye", - "fire", - "position", - "pressure", - "stress", - "advantage", - "benefit", - "box", - "frame", - "issue", - "step", - "cycle", - "face", - "item", - "metal", - "paint", - "review", - "room", - "screen", - "structure", - "view", - "account", - "ball", - "discipline", - "medium", - "share", - "balance", - "bit", - "black", - "bottom", - "choice", - "gift", - "impact", - "machine", - "shape", - "tool", - "wind", - "address", - "average", - "career", - "culture", - "morning", - "pot", - "sign", - "table", - "task", - "condition", - "contact", - "credit", - "egg", - "hope", - "ice", - "network", - "north", - "square", - "attempt", - "date", - "effect", - "link", - "post", - "star", - "voice", - "capital", - "challenge", - "friend", - "self", - "shot", - "brush", - "couple", - "exit", - "front", - "function", - "lack", - "living", - "plant", - "plastic", - "spot", - "summer", - "taste", - "theme", - "track", - "wing", - "brain", - "button", - "click", - "desire", - "foot", - "gas", - "influence", - "notice", - "rain", - "wall", - "base", - "damage", - "distance", - "feeling", - "pair", - "savings", - "staff", - "sugar", - "target", - "text", - "animal", - "author", - "budget", - "discount", - "file", - "ground", - "lesson", - "minute", - "officer", - "phase", - "reference", - "register", - "sky", - "stage", - "stick", - "title", - "trouble", - "bowl", - "bridge", - "campaign", - "character", - "club", - "edge", - "evidence", - "fan", - "letter", - "lock", - "maximum", - "novel", - "option", - "pack", - "park", - "quarter", - "skin", - "sort", - "weight", - "baby", - "background", - "carry", - "dish", - "factor", - "fruit", - "glass", - "joint", - "master", - "muscle", - "red", - "strength", - "traffic", - "trip", - "vegetable", - "appeal", - "chart", - "gear", - "ideal", - "kitchen", - "land", - "log", - "mother", - "net", - "party", - "principle", - "relative", - "sale", - "season", - "signal", - "spirit", - "street", - "tree", - "wave", - "belt", - "bench", - "commission", - "copy", - "drop", - "minimum", - "path", - "progress", - "project", - "sea", - "south", - "status", - "stuff", - "ticket", - "tour", - "angle", - "blue", - "breakfast", - "confidence", - "daughter", - "degree", - "doctor", - "dot", - "dream", - "duty", - "essay", - "father", - "fee", - "finance", - "hour", - "juice", - "luck", - "milk", - "mouth", - "peace", - "pipe", - "stable", - "storm", - "substance", - "team", - "trick", - "afternoon", - "bat", - "beach", - "blank", - "catch", - "chain", - "consideration", - "cream", - "crew", - "detail", - "gold", - "interview", - "kid", - "mark", - "mission", - "pain", - "pleasure", - "score", - "screw", - "sex", - "shop", - "shower", - "suit", - "tone", - "window", - "agent", - "band", - "bath", - "block", - "bone", - "calendar", - "candidate", - "cap", - "coat", - "contest", - "corner", - "court", - "cup", - "district", - "door", - "east", - "finger", - "garage", - "guarantee", - "hole", - "hook", - "implement", - "layer", - "lecture", - "lie", - "manner", - "meeting", - "nose", - "parking", - "partner", - "profile", - "rice", - "routine", - "schedule", - "swimming", - "telephone", - "tip", - "winter", - "airline", - "bag", - "battle", - "bed", - "bill", - "bother", - "cake", - "code", - "curve", - "designer", - "dimension", - "dress", - "ease", - "emergency", - "evening", - "extension", - "farm", - "fight", - "gap", - "grade", - "holiday", - "horror", - "horse", - "host", - "husband", - "loan", - "mistake", - "mountain", - "nail", - "noise", - "occasion", - "package", - "patient", - "pause", - "phrase", - "proof", - "race", - "relief", - "sand", - "sentence", - "shoulder", - "smoke", - "stomach", - "string", - "tourist", - "towel", - "vacation", - "west", - "wheel", - "wine", - "arm", - "aside", - "associate", - "bet", - "blow", - "border", - "branch", - "breast", - "brother", - "buddy", - "bunch", - "chip", - "coach", - "cross", - "document", - "draft", - "dust", - "expert", - "floor", - "god", - "golf", - "habit", - "iron", - "judge", - "knife", - "landscape", - "league", - "mail", - "mess", - "native", - "opening", - "parent", - "pattern", - "pin", - "pool", - "pound", - "request", - "salary", - "shame", - "shelter", - "shoe", - "silver", - "tackle", - "tank", - "trust", - "assist", - "bake", - "bar", - "bell", - "bike", - "blame", - "boy", - "brick", - "chair", - "closet", - "clue", - "collar", - "comment", - "conference", - "devil", - "diet", - "fear", - "fuel", - "glove", - "jacket", - "lunch", - "monitor", - "mortgage", - "nurse", - "pace", - "panic", - "peak", - "plane", - "reward", - "row", - "sandwich", - "shock", - "spite", - "spray", - "surprise", - "till", - "transition", - "weekend", - "welcome", - "yard", - "alarm", - "bend", - "bicycle", - "bite", - "blind", - "bottle", - "cable", - "candle", - "clerk", - "cloud", - "concert", - "counter", - "flower", - "grandfather", - "harm", - "knee", - "lawyer", - "leather", - "load", - "mirror", - "neck", - "pension", - "plate", - "purple", - "ruin", - "ship", - "skirt", - "slice", - "snow", - "specialist", - "stroke", - "switch", - "trash", - "tune", - "zone", - "anger", - "award", - "bid", - "bitter", - "boot", - "bug", - "camp", - "candy", - "carpet", - "cat", - "champion", - "channel", - "clock", - "comfort", - "cow", - "crack", - "engineer", - "entrance", - "fault", - "grass", - "guy", - "hell", - "highlight", - "incident", - "island", - "joke", - "jury", - "leg", - "lip", - "mate", - "motor", - "nerve", - "passage", - "pen", - "pride", - "priest", - "prize", - "promise", - "resident", - "resort", - "ring", - "roof", - "rope", - "sail", - "scheme", - "script", - "sock", - "station", - "toe", - "tower", - "truck", - "witness", - "can", - "will", - "other", - "use", - "make", - "good", - "look", - "help", - "go", - "great", - "being", - "still", - "public", - "read", - "keep", - "start", - "give", - "human", - "local", - "general", - "specific", - "long", - "play", - "feel", - "high", - "put", - "common", - "set", - "change", - "simple", - "past", - "big", - "possible", - "particular", - "major", - "personal", - "current", - "national", - "cut", - "natural", - "physical", - "show", - "try", - "check", - "second", - "call", - "move", - "pay", - "let", - "increase", - "single", - "individual", - "turn", - "ask", - "buy", - "guard", - "hold", - "main", - "offer", - "potential", - "professional", - "international", - "travel", - "cook", - "alternative", - "special", - "working", - "whole", - "dance", - "excuse", - "cold", - "commercial", - "low", - "purchase", - "deal", - "primary", - "worth", - "fall", - "necessary", - "positive", - "produce", - "search", - "present", - "spend", - "talk", - "creative", - "tell", - "cost", - "drive", - "green", - "support", - "glad", - "remove", - "return", - "run", - "complex", - "due", - "effective", - "middle", - "regular", - "reserve", - "independent", - "leave", - "original", - "reach", - "rest", - "serve", - "watch", - "beautiful", - "charge", - "active", - "break", - "negative", - "safe", - "stay", - "visit", - "visual", - "affect", - "cover", - "report", - "rise", - "walk", - "white", - "junior", - "pick", - "unique", - "classic", - "final", - "lift", - "mix", - "private", - "stop", - "teach", - "western", - "concern", - "familiar", - "fly", - "official", - "broad", - "comfortable", - "gain", - "rich", - "save", - "stand", - "young", - "heavy", - "lead", - "listen", - "valuable", - "worry", - "handle", - "leading", - "meet", - "release", - "sell", - "finish", - "normal", - "press", - "ride", - "secret", - "spread", - "spring", - "tough", - "wait", - "brown", - "deep", - "display", - "flow", - "hit", - "objective", - "shoot", - "touch", - "cancel", - "chemical", - "cry", - "dump", - "extreme", - "push", - "conflict", - "eat", - "fill", - "formal", - "jump", - "kick", - "opposite", - "pass", - "pitch", - "remote", - "total", - "treat", - "vast", - "abuse", - "beat", - "burn", - "deposit", - "print", - "raise", - "sleep", - "somewhere", - "advance", - "consist", - "dark", - "double", - "draw", - "equal", - "fix", - "hire", - "internal", - "join", - "kill", - "sensitive", - "tap", - "win", - "attack", - "claim", - "constant", - "drag", - "drink", - "guess", - "minor", - "pull", - "raw", - "soft", - "solid", - "wear", - "weird", - "wonder", - "annual", - "count", - "dead", - "doubt", - "feed", - "forever", - "impress", - "repeat", - "round", - "sing", - "slide", - "strip", - "wish", - "combine", - "command", - "dig", - "divide", - "equivalent", - "hang", - "hunt", - "initial", - "march", - "mention", - "spiritual", - "survey", - "tie", - "adult", - "brief", - "crazy", - "escape", - "gather", - "hate", - "prior", - "repair", - "rough", - "sad", - "scratch", - "sick", - "strike", - "employ", - "external", - "hurt", - "illegal", - "laugh", - "lay", - "mobile", - "nasty", - "ordinary", - "respond", - "royal", - "senior", - "split", - "strain", - "struggle", - "swim", - "train", - "upper", - "wash", - "yellow", - "convert", - "crash", - "dependent", - "fold", - "funny", - "grab", - "hide", - "miss", - "permit", - "quote", - "recover", - "resolve", - "roll", - "sink", - "slip", - "spare", - "suspect", - "sweet", - "swing", - "twist", - "upstairs", - "usual", - "abroad", - "brave", - "calm", - "concentrate", - "estimate", - "grand", - "male", - "mine", - "prompt", - "quiet", - "refuse", - "regret", - "reveal", - "rush", - "shake", - "shift", - "shine", - "steal", - "suck", - "surround", - "bear", - "brilliant", - "dare", - "dear", - "delay", - "drunk", - "female", - "hurry", - "inevitable", - "invite", - "kiss", - "neat", - "pop", - "punch", - "quit", - "reply", - "representative", - "resist", - "rip", - "rub", - "silly", - "smile", - "spell", - "stretch", - "stupid", - "tear", - "temporary", - "tomorrow", - "wake", - "wrap", - "yesterday", - "Thomas", - "Tom", - "Lieuwe", - ]; - - const name = - name1[getRandomInt(0, name1.length + 1)] + - name2[getRandomInt(0, name2.length + 1)]; - return name; -}; diff --git a/packages/manifest-schemas/formats/web3api.app/0.0.1-prealpha.2.json b/packages/manifest-schemas/formats/web3api.app/0.0.1-prealpha.2.json new file mode 100644 index 0000000000..cbfd7076b8 --- /dev/null +++ b/packages/manifest-schemas/formats/web3api.app/0.0.1-prealpha.2.json @@ -0,0 +1,50 @@ +{ + "id": "AppManifest", + "type": "object", + "additionalProperties": false, + "required": [ + "format", + "name", + "language", + "schema" + ], + "properties": { + "format": { + "type": "string", + "const": "0.0.1-prealpha.2" + }, + "name": { + "type": "string", + "format": "packageName" + }, + "language": { + "type": "string", + "format": "appLanguage" + }, + "schema": { + "type": "string", + "format": "file" + }, + "import_redirects": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "uri": { + "type": "string", + "format": "web3apiUri" + }, + "schema": { + "type": "string", + "format": "schemaFile" + } + }, + "required": [ + "uri", + "schema" + ] + } + } + } +} diff --git a/packages/manifest-schemas/formats/web3api.plugin/0.0.1-prealpha.2.json b/packages/manifest-schemas/formats/web3api.plugin/0.0.1-prealpha.2.json new file mode 100644 index 0000000000..b57184edf9 --- /dev/null +++ b/packages/manifest-schemas/formats/web3api.plugin/0.0.1-prealpha.2.json @@ -0,0 +1,84 @@ +{ + "id": "PluginManifest", + "type": "object", + "additionalProperties": false, + "required": [ + "format", + "name", + "language", + "modules" + ], + "properties": { + "format": { + "type": "string", + "const": "0.0.1-prealpha.2" + }, + "name": { + "type": "string", + "format": "packageName" + }, + "language": { + "type": "string", + "format": "pluginLanguage" + }, + "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" + ] + } + } + } +} diff --git a/packages/schema/bind/package.json b/packages/schema/bind/package.json index 3d8d2e8de9..064774176b 100644 --- a/packages/schema/bind/package.json +++ b/packages/schema/bind/package.json @@ -21,13 +21,14 @@ }, "dependencies": { "@web3api/os-js": "0.0.1-prealpha.71", + "@web3api/schema-compose": "0.0.1-prealpha.71", "@web3api/schema-parse": "0.0.1-prealpha.71", "mustache": "4.0.1" }, "devDependencies": { + "@types/lodash": "4.14.178", "@types/jest": "26.0.8", "@types/mustache": "4.0.1", - "@web3api/schema-compose": "0.0.1-prealpha.71", "@web3api/test-cases": "0.0.1-prealpha.71", "copyfiles": "2.4.1", "jest": "26.6.3", diff --git a/packages/schema/bind/src/__tests__/index.ts b/packages/schema/bind/src/__tests__/index.ts index f326ca3042..b29925f12c 100644 --- a/packages/schema/bind/src/__tests__/index.ts +++ b/packages/schema/bind/src/__tests__/index.ts @@ -3,7 +3,12 @@ import { BindModuleOptions } from "../"; import fs from "fs"; import path from "path"; import { TypeInfo } from "@web3api/schema-parse"; -import { composeSchema, SchemaFile, ComposerFilter, SchemaKind } from "@web3api/schema-compose"; +import { + composeSchema, + SchemaFile, + ComposerFilter, + SchemaKind, +} from "@web3api/schema-compose"; import { GetPathToBindTestFiles } from "@web3api/test-cases"; import { normalizeLineEndings } from "@web3api/os-js"; @@ -36,9 +41,7 @@ export type TestCases = { export function fetchTestCases(): TestCases { const cases: TestCases = []; - const fetchIfExists = ( - file: string - ): string | undefined => { + const fetchIfExists = (file: string): string | undefined => { if (fs.existsSync(file)) { return normalizeLineEndings( fs.readFileSync(file, { encoding: "utf-8" }), @@ -49,22 +52,35 @@ export function fetchTestCases(): TestCases { } }; - const importCase = async (dirent: fs.Dirent): Promise => { + const importCase = async ( + dirent: fs.Dirent + ): Promise => { // The case must be a folder if (!dirent.isDirectory()) { return Promise.resolve(undefined); } // Fetch the input schemas - const querySchemaFile = path.join(root, dirent.name, "input", "query.graphql"); - const mutationSchemaFile = path.join(root, dirent.name, "input", "mutation.graphql"); + const querySchemaFile = path.join( + root, + dirent.name, + "input", + "query.graphql" + ); + const mutationSchemaFile = path.join( + root, + dirent.name, + "input", + "mutation.graphql" + ); const querySchema = fetchIfExists(querySchemaFile); const mutationSchema = fetchIfExists(mutationSchemaFile); // Fetch each language's expected output const outputDir = path.join(root, dirent.name, "output"); - const outputLanguages = fs.readdirSync(outputDir, { withFileTypes: true }) + const outputLanguages = fs + .readdirSync(outputDir, { withFileTypes: true }) .filter((item: fs.Dirent) => item.isDirectory()) .map((item: fs.Dirent) => { const outputLanguageDir = path.join(outputDir, item.name); @@ -98,19 +114,19 @@ export function fetchTestCases(): TestCases { }; }); - let schemas: Partial> = { }; + let schemas: Partial> = {}; if (querySchema) { schemas["query"] = { schema: querySchema, - absolutePath: querySchemaFile + absolutePath: querySchemaFile, }; } if (mutationSchema) { schemas["mutation"] = { schema: mutationSchema, - absolutePath: mutationSchemaFile + absolutePath: mutationSchemaFile, }; } @@ -129,10 +145,10 @@ export function fetchTestCases(): TestCases { }, local: (path: string): Promise => { return Promise.resolve(fetchIfExists(path) || ""); - } + }, }, - output: ComposerFilter.All - }) + output: ComposerFilter.All, + }); const modules: BindModuleOptions[] = []; @@ -170,14 +186,14 @@ export function fetchTestCases(): TestCases { combined, commonDirAbs: path.join(root, "common"), }, - outputLanguages + outputLanguages, }; }; fs.readdirSync(root, { withFileTypes: true }).forEach((dirent: fs.Dirent) => { cases.push({ name: dirent.name, - promise: importCase(dirent) + promise: importCase(dirent), }); }); diff --git a/packages/schema/bind/src/__tests__/test-cases.spec.ts b/packages/schema/bind/src/__tests__/test-cases.spec.ts index 27f498cbd5..f5d8d0aef0 100644 --- a/packages/schema/bind/src/__tests__/test-cases.spec.ts +++ b/packages/schema/bind/src/__tests__/test-cases.spec.ts @@ -81,6 +81,7 @@ describe("Web3API Binding Test Suite", () => { .indexOf("common") > -1; const moduleWiseOutput = expectedModuleWiseOutput ? bindSchema({ + projectName: "TestCase", bindLanguage: language as BindLanguage, modules, commonDirAbs: hasCommonModule ? commonDirAbs : undefined @@ -89,6 +90,7 @@ describe("Web3API Binding Test Suite", () => { const combinedOutput = expectedCombinedOutput ? bindSchema({ + projectName: "TestCase", bindLanguage: language as BindLanguage, modules: [testCase.input.combined] }) diff --git a/packages/schema/bind/src/bindings/assemblyscript/wasm-as/index.ts b/packages/schema/bind/src/bindings/assemblyscript/wasm-as/index.ts index 088ec8600c..a904a16469 100644 --- a/packages/schema/bind/src/bindings/assemblyscript/wasm-as/index.ts +++ b/packages/schema/bind/src/bindings/assemblyscript/wasm-as/index.ts @@ -1,6 +1,7 @@ import * as Functions from "./functions"; import { GenerateBindingFn } from "../.."; import { extractCommonTypeInfo } from "../../utils/typeInfo"; +import { renderTemplates, loadSubTemplates } from "../../utils/templates"; import { BindOptions, BindOutput, @@ -17,9 +18,13 @@ import { toPrefixedGraphQLType, } from "@web3api/schema-parse"; import { OutputEntry, readDirectorySync } from "@web3api/os-js"; -import Mustache from "mustache"; import path from "path"; +const templatesDir = readDirectorySync(path.join(__dirname, "./templates")); +const subTemplates = loadSubTemplates(templatesDir.entries); +const templatePath = (subpath: string) => + path.join(__dirname, "./templates", subpath); + export const generateBinding: GenerateBindingFn = ( options: BindOptions ): BindOutput => { @@ -65,10 +70,7 @@ function applyTransforms(typeInfo: TypeInfo): TypeInfo { return typeInfo; } -const templatesDir = readDirectorySync(path.join(__dirname, "./templates")); - function generateModuleBinding(module: BindModuleOptions): BindModuleOutput { - const subTemplates = loadSubTemplates(templatesDir.entries); const result: BindModuleOutput = { name: module.name, output: { @@ -84,7 +86,11 @@ function generateModuleBinding(module: BindModuleOptions): BindModuleOutput { output.entries.push({ type: "Directory", name: objectType.type, - data: generateFiles("./templates/object-type", objectType, subTemplates), + data: renderTemplates( + templatePath("object-type"), + objectType, + subTemplates + ), }); } @@ -96,8 +102,8 @@ function generateModuleBinding(module: BindModuleOptions): BindModuleOutput { importEntries.push({ type: "Directory", name: importedModuleType.type, - data: generateFiles( - "./templates/imported/module-type", + data: renderTemplates( + templatePath("imported/module-type"), importedModuleType, subTemplates ), @@ -109,8 +115,8 @@ function generateModuleBinding(module: BindModuleOptions): BindModuleOutput { importEntries.push({ type: "Directory", name: importedEnumType.type, - data: generateFiles( - "./templates/imported/enum-type", + data: renderTemplates( + templatePath("imported/enum-type"), importedEnumType, subTemplates ), @@ -122,8 +128,8 @@ function generateModuleBinding(module: BindModuleOptions): BindModuleOutput { importEntries.push({ type: "Directory", name: importedObectType.type, - data: generateFiles( - "./templates/imported/object-type", + data: renderTemplates( + templatePath("imported/object-type"), importedObectType, subTemplates ), @@ -136,7 +142,7 @@ function generateModuleBinding(module: BindModuleOptions): BindModuleOutput { name: "imported", data: [ ...importEntries, - ...generateFiles("./templates/imported", typeInfo, subTemplates), + ...renderTemplates(templatePath("imported"), typeInfo, subTemplates), ], }); } @@ -146,8 +152,8 @@ function generateModuleBinding(module: BindModuleOptions): BindModuleOutput { output.entries.push({ type: "Directory", name: interfaceType.type, - data: generateFiles( - "./templates/interface-type", + data: renderTemplates( + templatePath("interface-type"), interfaceType, subTemplates ), @@ -159,7 +165,11 @@ function generateModuleBinding(module: BindModuleOptions): BindModuleOutput { output.entries.push({ type: "Directory", name: moduleType.type, - data: generateFiles("./templates/module-type", moduleType, subTemplates), + data: renderTemplates( + templatePath("module-type"), + moduleType, + subTemplates + ), }); } @@ -168,7 +178,7 @@ function generateModuleBinding(module: BindModuleOptions): BindModuleOutput { output.entries.push({ type: "Directory", name: enumType.type, - data: generateFiles("./templates/enum-type", enumType, subTemplates), + data: renderTemplates(templatePath("enum-type"), enumType, subTemplates), }); } @@ -178,7 +188,7 @@ function generateModuleBinding(module: BindModuleOptions): BindModuleOutput { output.entries.push({ type: "Directory", name: def.type, - data: generateFiles("./templates/object-type", def, subTemplates), + data: renderTemplates(templatePath("object-type"), def, subTemplates), }); }; generateEnvTypeFolder(typeInfo.envTypes.query.client); @@ -187,81 +197,9 @@ function generateModuleBinding(module: BindModuleOptions): BindModuleOutput { generateEnvTypeFolder(typeInfo.envTypes.mutation.sanitized); // Generate root entry file - output.entries.push(...generateFiles("./templates", typeInfo, subTemplates)); + output.entries.push( + ...renderTemplates(templatePath(""), typeInfo, subTemplates) + ); return result; } - -function generateFiles( - subpath: string, - view: unknown, - subTemplates: Record, - subDirectories = false -): OutputEntry[] { - const output: OutputEntry[] = []; - const absolutePath = path.join(__dirname, subpath); - const directory = readDirectorySync(absolutePath); - - const processDirectory = (entries: OutputEntry[], output: OutputEntry[]) => { - subTemplates = loadSubTemplates(entries, subTemplates); - - // Generate all files, recurse all directories - for (const dirent of entries) { - if (dirent.type === "File") { - const name = path.parse(dirent.name).name; - - // file templates don't contain '_' - if (name.indexOf("_") === -1) { - const data = Mustache.render(dirent.data, view, subTemplates); - - // If the file isn't empty, add it to the output - if (data) { - output.push({ - type: "File", - name: name.replace("-", "."), - data, - }); - } - } - } else if (dirent.type === "Directory" && subDirectories) { - const subOutput: OutputEntry[] = []; - - processDirectory(dirent.data as OutputEntry[], subOutput); - - output.push({ - type: "Directory", - name: dirent.name, - data: subOutput, - }); - } - } - }; - - processDirectory(directory.entries, output); - - return output; -} - -function loadSubTemplates( - entries: OutputEntry[], - existingSubTemplates?: Record -): Record { - const subTemplates: Record = existingSubTemplates - ? existingSubTemplates - : {}; - - for (const file of entries) { - if (file.type !== "File") { - continue; - } - - const name = path.parse(file.name).name; - - // sub-templates contain '_' in their file names - if (name.indexOf("_") > -1) { - subTemplates[name] = file.data as string; - } - } - - return subTemplates; -} diff --git a/packages/schema/bind/src/bindings/assemblyscript/wasm-as/templates/entry-ts.mustache b/packages/schema/bind/src/bindings/assemblyscript/wasm-as/templates/entry-ts.mustache index 3fe4de31ba..4b8164531e 100644 --- a/packages/schema/bind/src/bindings/assemblyscript/wasm-as/templates/entry-ts.mustache +++ b/packages/schema/bind/src/bindings/assemblyscript/wasm-as/templates/entry-ts.mustache @@ -68,13 +68,13 @@ export function _w3_load_env(env_size: u32): void { {{/envTypes.mutation.sanitized}} {{#envTypes.query.client}} export function _w3_sanitize_env(args_size: u32): void { - w3_sanitize_env(args_size, sanitizeQueryEnvWrapped); + w3_sanitize_env(args_size, sanitizeEnvWrapped); } {{/envTypes.query.client}} {{#envTypes.mutation.client}} export function _w3_sanitize_env(args_size: u32): void { - w3_sanitize_env(args_size, sanitizeMutationEnvWrapped) + w3_sanitize_env(args_size, sanitizeEnvWrapped) } {{/envTypes.mutation.client}} diff --git a/packages/schema/bind/src/bindings/typescript/app-ts/index.ts b/packages/schema/bind/src/bindings/typescript/app-ts/index.ts index a35f6782b6..24957a8a41 100644 --- a/packages/schema/bind/src/bindings/typescript/app-ts/index.ts +++ b/packages/schema/bind/src/bindings/typescript/app-ts/index.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import * as Functions from "../functions"; import { GenerateBindingFn } from "../.."; +import { renderTemplates } from "../../utils/templates"; import { BindOptions, BindOutput, @@ -16,8 +17,6 @@ import { methodParentPointers, TypeInfo, } from "@web3api/schema-parse"; -import Mustache from "mustache"; -import { readFileSync } from "fs"; import path from "path"; export { Functions }; @@ -62,37 +61,11 @@ function generateModuleBindings(module: BindModuleOptions): BindModuleOutput { const schema = module.schema; const typeInfo = applyTransforms(module.typeInfo); - const renderTemplate = ( - subPath: string, - context: unknown, - fileName?: string - ) => { - const absPath = path.join(__dirname, subPath); - const template = readFileSync(absPath, { encoding: "utf-8" }); - fileName = - fileName || - absPath - .replace(path.dirname(absPath), "") - .replace(".mustache", "") - .replace("/", "") - .replace("\\", "") - .replace("-", "."); - - output.entries.push({ - type: "File", - name: fileName, - data: Mustache.render(template, context), - }); - }; - - const rootContext = { - ...typeInfo, - schema, - }; - - renderTemplate("./templates/index-ts.mustache", rootContext); - renderTemplate("./templates/schema-ts.mustache", rootContext); - renderTemplate("./templates/types-ts.mustache", rootContext); + output.entries = renderTemplates( + path.join(__dirname, "./templates"), + { ...typeInfo, schema }, + {} + ); return result; } diff --git a/packages/schema/bind/src/bindings/typescript/app-ts/templates/types-ts.mustache b/packages/schema/bind/src/bindings/typescript/app-ts/templates/types-ts.mustache index 3b30c29805..82e03b1905 100644 --- a/packages/schema/bind/src/bindings/typescript/app-ts/templates/types-ts.mustache +++ b/packages/schema/bind/src/bindings/typescript/app-ts/templates/types-ts.mustache @@ -1,6 +1,7 @@ -// @ts-noCheck +// @ts-ignore import * as Types from "./"; +// @ts-ignore import { Client, InvokeApiResult diff --git a/packages/schema/bind/src/bindings/typescript/functions.ts b/packages/schema/bind/src/bindings/typescript/functions.ts index 628393a9ac..816a33c264 100644 --- a/packages/schema/bind/src/bindings/typescript/functions.ts +++ b/packages/schema/bind/src/bindings/typescript/functions.ts @@ -1,5 +1,43 @@ import { MustacheFn } from "../types"; +const firstUpper = (str: string) => + str ? str[0].toUpperCase() + str.slice(1) : ""; + +const firstLower = (str: string) => + str ? str[0].toLowerCase() + str.slice(1) : ""; + +export const toLowerCase: MustacheFn = () => { + return (value: string, render: (template: string) => string) => { + const rendered = render(value); + return rendered.toLowerCase(); + }; +}; + +export const toClassName: MustacheFn = () => { + return (value: string, render: (template: string) => string) => { + const rendered = render(value); + rendered.replace(/([^A-Za-z0-9])+/g, ","); + return rendered + .split(",") + .map((x) => (x ? firstUpper(x.replace(",", "")) : "")) + .join(); + }; +}; + +export const toFuncName: MustacheFn = () => { + return (value: string, render: (template: string) => string) => { + let rendered = render(value); + rendered = rendered.replace(/([^A-Za-z])+/g, ","); + return rendered + .split(",") + .map((x, index) => { + x = x.replace(",", ""); + return index === 0 ? firstLower(x) : firstUpper(x); + }) + .join(); + }; +}; + export const toTypescript: MustacheFn = () => { return _toTypescript; }; @@ -27,20 +65,6 @@ const _toTypescript = ( } switch (type) { - case "Int": - case "Int8": - case "Int16": - case "Int32": - case "UInt": - case "UInt32": - case "UInt8": - case "UInt16": - case "String": - case "Boolean": - case "Bytes": - case "BigInt": - case "BigNumber": - break; case "JSON": type = "Json"; break; diff --git a/packages/schema/bind/src/bindings/typescript/plugin-ts/index.ts b/packages/schema/bind/src/bindings/typescript/plugin-ts/index.ts index 2835793444..1b7da02e71 100644 --- a/packages/schema/bind/src/bindings/typescript/plugin-ts/index.ts +++ b/packages/schema/bind/src/bindings/typescript/plugin-ts/index.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import * as Functions from "../functions"; import { GenerateBindingFn } from "../.."; +import { renderTemplates } from "../../utils/templates"; import { BindOptions, BindOutput, @@ -10,20 +11,22 @@ import { import { TypeInfo, - ModuleDefinition, transformTypeInfo, extendType, addFirstLast, toPrefixedGraphQLType, methodParentPointers, interfaceUris, + combineTypeInfo, } from "@web3api/schema-parse"; -import Mustache from "mustache"; -import { readFileSync } from "fs"; +import { renderSchema } from "@web3api/schema-compose"; import path from "path"; export { Functions }; +const templatePath = (subpath: string) => + path.join(__dirname, "./templates", subpath); + export const generateBinding: GenerateBindingFn = ( options: BindOptions ): BindOutput => { @@ -31,6 +34,41 @@ export const generateBinding: GenerateBindingFn = ( modules: [], }; + // Require a common directory + if (!options.commonDirAbs) { + throw new Error("plugin-ts schema binding requires a common directory."); + } + + // Aggregate the schemas (will be removed once user-defined modules are supported) + const schema = renderSchema( + combineTypeInfo(options.modules.map((m) => m.typeInfo)), + true + ); + + // Apply TypeInfo transforms + options.modules = options.modules.map((m) => ({ + ...m, + typeInfo: applyTransforms(m.typeInfo), + })); + + // Generate root entry point files + result.common = { + name: "common", + output: { + entries: renderTemplates( + templatePath(""), + { + ...options, + ...Functions, + schema, + }, + {} + ), + }, + outputDirAbs: options.commonDirAbs, + }; + + // Generate each module for (const module of options.modules) { result.modules.push(generateModuleBindings(module)); } @@ -62,60 +100,12 @@ function generateModuleBindings(module: BindModuleOptions): BindModuleOutput { outputDirAbs: module.outputDirAbs, }; const output = result.output; - const schema = module.schema; - const typeInfo = applyTransforms(module.typeInfo); - const renderTemplate = ( - subPath: string, - context: unknown, - fileName?: string - ) => { - const absPath = path.join(__dirname, subPath); - const template = readFileSync(absPath, { encoding: "utf-8" }); - fileName = - fileName || - absPath - .replace(path.dirname(absPath), "") - .replace(".mustache", "") - .replace("/", "") - .replace("\\", "") - .replace("-", "."); - - output.entries.push({ - type: "File", - name: fileName, - data: Mustache.render(template, context), - }); - }; - - const queryContext = typeInfo.moduleTypes.find((def: ModuleDefinition) => { - return def.type === "Query"; - }); - const mutationContext = typeInfo.moduleTypes.find((def: ModuleDefinition) => { - return def.type === "Mutation"; - }); - - const rootContext = { - ...typeInfo, - schema, - __mutation: !!mutationContext, - __query: !!queryContext, - }; - - renderTemplate("./templates/index-ts.mustache", rootContext); - renderTemplate("./templates/manifest-ts.mustache", rootContext); - if (mutationContext) { - renderTemplate( - "./templates/module_ts.mustache", - mutationContext, - "mutation.ts" - ); - } - if (queryContext) { - renderTemplate("./templates/module_ts.mustache", queryContext, "query.ts"); - } - renderTemplate("./templates/schema-ts.mustache", rootContext); - renderTemplate("./templates/types-ts.mustache", rootContext); + output.entries = renderTemplates( + templatePath("module-type"), + module.typeInfo, + {} + ); return result; } diff --git a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/index-ts.mustache b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/index-ts.mustache index cd1552743f..6c0a9a1500 100644 --- a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/index-ts.mustache +++ b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/index-ts.mustache @@ -1,9 +1,6 @@ -{{#__query}} -export * as Query from "./query"; -{{/__query}} -{{#__mutation}} -export * as Mutation from "./mutation"; -{{/__mutation}} -export * from "./types"; +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + export * from "./schema"; export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/manifest-ts.mustache b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/manifest-ts.mustache index ef22d2dced..edc98649c7 100644 --- a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/manifest-ts.mustache +++ b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/manifest-ts.mustache @@ -1,6 +1,11 @@ -// @ts-noCheck +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +/* eslint-disable @typescript-eslint/no-unused-vars */ + import { schema } from "./"; +// @ts-ignore import { PluginPackageManifest, Uri } from "@web3api/core-js"; export const manifest: PluginPackageManifest = { @@ -10,4 +15,4 @@ export const manifest: PluginPackageManifest = { new Uri("{{.}}"), {{/interfaceUris}} ], -} +}; diff --git a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module-type/index-ts.mustache b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module-type/index-ts.mustache new file mode 100644 index 0000000000..efe3c2530f --- /dev/null +++ b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module-type/index-ts.mustache @@ -0,0 +1,7 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/client-js"; diff --git a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module-type/module-ts.mustache b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module-type/module-ts.mustache new file mode 100644 index 0000000000..1c06cd8931 --- /dev/null +++ b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module-type/module-ts.mustache @@ -0,0 +1,40 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import * as Types from "./types"; + +import { + Client, + PluginModule, + MaybeAsync +} from "@web3api/core-js"; +{{#moduleTypes}} +{{#methods}} + +export interface Input_{{name}} extends Record { + {{#arguments}} + {{name}}{{^required}}?{{/required}}: {{#toTypescript}}{{toGraphQLType}}{{/toTypescript}}; + {{/arguments}} +} +{{/methods}} +{{/moduleTypes}} + +export abstract class Module< + TConfig extends Record +> extends PluginModule< + TConfig{{#envTypes.query.sanitized}}, + Types.QueryEnv{{#envTypes.query.client}}, + Types.QueryClientEnv{{/envTypes.query.client}}{{/envTypes.query.sanitized}}{{#envTypes.mutation.sanitized}}, + Types.MutationEnv{{#envTypes.mutation.client}}, + Types.MutationClientEnv{{/envTypes.mutation.client}}{{/envTypes.mutation.sanitized}} +> { + {{#moduleTypes}} + {{#methods}} + + abstract {{name}}( + input: Input_{{name}}, + client: Client + ): MaybeAsync<{{#return}}{{#toTypescript}}{{toGraphQLType}}{{/toTypescript}}{{/return}}>; + {{/methods}} + {{/moduleTypes}} +} diff --git a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/types-ts.mustache b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module-type/types-ts.mustache similarity index 84% rename from packages/schema/bind/src/bindings/typescript/plugin-ts/templates/types-ts.mustache rename to packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module-type/types-ts.mustache index 1af6269842..458ec5227e 100644 --- a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/types-ts.mustache +++ b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module-type/types-ts.mustache @@ -1,6 +1,10 @@ -// @ts-noCheck +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +// @ts-ignore import * as Types from "./"; +// @ts-ignore import { Client, InvokeApiResult @@ -20,48 +24,57 @@ export type BigNumber = string; export type Json = string; export type String = string; export type Boolean = boolean; -{{#envTypes.query.client}} -export interface {{type}} { +/// Envs START /// +{{#envTypes}} +{{#query}} +{{#client}} +export interface {{type}} extends Record { {{#properties}} {{name}}{{^required}}?{{/required}}: {{#toTypescript}}{{toGraphQLType}}{{/toTypescript}}; {{/properties}} } -{{/envTypes.query.client}} -{{#envTypes.query.sanitized}} - -export interface {{type}} { +{{/client}} +{{#sanitized}} +export interface {{type}} extends Record { {{#properties}} {{name}}{{^required}}?{{/required}}: {{#toTypescript}}{{toGraphQLType}}{{/toTypescript}}; {{/properties}} } -{{/envTypes.query.sanitized}} -{{#envTypes.mutation.client}} - -export interface {{type}} { +{{/sanitized}} +{{/query}} +{{#mutation}} +{{#client}} +export interface {{type}} extends Record { {{#properties}} {{name}}{{^required}}?{{/required}}: {{#toTypescript}}{{toGraphQLType}}{{/toTypescript}}; {{/properties}} } -{{/envTypes.mutation.client}} -{{#envTypes.mutation.sanitized}} - -export interface {{type}} { +{{/client}} +{{#sanitized}} +export interface {{type}} extends Record { {{#properties}} {{name}}{{^required}}?{{/required}}: {{#toTypescript}}{{toGraphQLType}}{{/toTypescript}}; {{/properties}} } -{{/envTypes.mutation.sanitized}} -{{#objectTypes}} +{{/sanitized}} +{{/mutation}} +{{/envTypes}} +/// Envs END /// +/// Objects START /// +{{#objectTypes}} export interface {{type}} { {{#properties}} {{name}}{{^required}}?{{/required}}: {{#toTypescript}}{{toGraphQLType}}{{/toTypescript}}; {{/properties}} } + {{/objectTypes}} -{{#enumTypes}} +/// Objects END /// +/// Enums START /// +{{#enumTypes}} export enum {{type}}Enum { {{#constants}} {{.}}, @@ -74,27 +87,22 @@ export type {{type}}String = {{/constants}} export type {{type}} = {{type}}Enum | {{type}}String; + {{/enumTypes}} -{{#importedObjectTypes.length}} +/// Enums END /// /// Imported Objects START /// -{{#importedObjectTypes}} +{{#importedObjectTypes}} /* URI: "{{uri}}" */ export interface {{type}} { {{#properties}} {{name}}{{^required}}?{{/required}}: {{#toTypescript}}{{toGraphQLType}}{{/toTypescript}}; {{/properties}} } -{{/importedObjectTypes}} - -/// Imported Objects END /// -{{/importedObjectTypes.length}} -{{#importedEnumTypes.length}} -/// Imported Enums START /// +{{/importedObjectTypes}} {{#importedEnumTypes}} - /* URI: "{{uri}}" */ export enum {{type}}Enum { {{#constants}} @@ -108,24 +116,22 @@ export type {{type}}String = {{/constants}} export type {{type}} = {{type}}Enum | {{type}}String; -{{/importedEnumTypes}} -/// Imported Enums END /// -{{/importedEnumTypes.length}} -{{#importedModuleTypes.length}} +{{/importedEnumTypes}} +/// Imported Objects END /// /// Imported Queries START /// + {{#importedModuleTypes}} {{#methods}} - /* URI: "{{parent.uri}}" */ interface {{parent.type}}_Input_{{name}} extends Record { {{#arguments}} {{name}}{{^required}}?{{/required}}: {{#toTypescript}}{{toGraphQLType}}{{/toTypescript}}; {{/arguments}} } -{{/methods}} +{{/methods}} /* URI: "{{uri}}" */ {{^isInterface}} export const {{type}} = { @@ -146,6 +152,7 @@ export const {{type}} = { {{/last}} {{/methods}} } + {{/isInterface}} {{#isInterface}} export class {{type}} { @@ -165,21 +172,19 @@ export class {{type}} { method: "{{name}}", input }); - }{{^last}},{{/last}} + } {{^last}} {{/last}} {{/methods}} } -{{/isInterface}} +{{/isInterface}} {{/importedModuleTypes}} - /// Imported Queries END /// -{{/importedModuleTypes.length}} - {{#interfaceTypes.length}} {{#interfaceTypes}} + export class {{namespace}} { static uri: string = "{{uri}}"; @@ -194,4 +199,4 @@ export class {{namespace}} { {{/capabilities}} } {{/interfaceTypes}} -{{/interfaceTypes.length}} \ No newline at end of file +{{/interfaceTypes.length}} diff --git a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module_ts.mustache b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module_ts.mustache deleted file mode 100644 index 77a19d4aee..0000000000 --- a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/module_ts.mustache +++ /dev/null @@ -1,44 +0,0 @@ -// @ts-noCheck -import { - UInt, - UInt8, - UInt16, - UInt32, - Int, - Int8, - Int16, - Int32, - Bytes, - BigInt, - BigNumber, - Json, - String, - Boolean -} from "./types"; -import * as Types from "./types"; - -import { - Client, - PluginModule, - MaybeAsync -} from "@web3api/core-js"; - -{{#methods}} -export interface Input_{{name}} extends Record { - {{#arguments}} - {{name}}{{^required}}?{{/required}}: {{#toTypescript}}{{toGraphQLType}}{{/toTypescript}}; - {{/arguments}} -} - -{{/methods}} -export interface Module extends PluginModule { - {{#methods}} - {{name}}( - input: Input_{{name}}, - client: Client - ): MaybeAsync<{{#return}}{{#toTypescript}}{{toGraphQLType}}{{/toTypescript}}{{/return}}>; - {{^last}} - - {{/last}} - {{/methods}} -} diff --git a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/plugin-ts.mustache b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/plugin-ts.mustache new file mode 100644 index 0000000000..97ad6f377c --- /dev/null +++ b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/plugin-ts.mustache @@ -0,0 +1,46 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; +{{#modules}} +import { {{#toClassName}}{{name}}{{/toClassName}}, {{#toClassName}}{{name}}{{/toClassName}}Config } from "../{{name}}"; +{{/modules}} +import { manifest } from "./manifest"; + +export interface {{#toClassName}}{{projectName}}{{/toClassName}}PluginConfigs { +{{#modules}} + {{name}}: {{#toClassName}}{{name}}{{/toClassName}}Config; +{{/modules}} +} + +export class {{#toClassName}}{{projectName}}{{/toClassName}}Plugin implements Plugin { + constructor(private _configs: {{#toClassName}}{{projectName}}{{/toClassName}}PluginConfigs) { } + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + {{#modules}} + {{name}}: new {{#toClassName}}{{name}}{{/toClassName}}(this._configs.{{name}}), + {{/modules}} + }; + } +} + +export const {{#toFuncName}}{{projectName}}{{/toFuncName}}Plugin: PluginFactory<{{#toClassName}}{{projectName}}{{/toClassName}}PluginConfigs> = ( + opts: {{#toClassName}}{{projectName}}{{/toClassName}}PluginConfigs +) => { + return { + factory: () => new {{#toClassName}}{{projectName}}{{/toClassName}}Plugin(opts), + manifest: manifest, + }; +}; + +export const plugin = {{#toFuncName}}{{projectName}}{{/toFuncName}}Plugin; diff --git a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/schema-ts.mustache b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/schema-ts.mustache index 394b057efc..6f24be9051 100644 --- a/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/schema-ts.mustache +++ b/packages/schema/bind/src/bindings/typescript/plugin-ts/templates/schema-ts.mustache @@ -1 +1,4 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + export const schema: string = `{{schema}}`; diff --git a/packages/schema/bind/src/bindings/utils/templates.ts b/packages/schema/bind/src/bindings/utils/templates.ts new file mode 100644 index 0000000000..2923092b12 --- /dev/null +++ b/packages/schema/bind/src/bindings/utils/templates.ts @@ -0,0 +1,76 @@ +import { OutputEntry, readDirectorySync } from "@web3api/os-js"; +import Mustache from "mustache"; +import path from "path"; + +export function renderTemplates( + templateDirAbs: string, + view: unknown, + subTemplates: Record, + subDirectories = false +): OutputEntry[] { + const output: OutputEntry[] = []; + const directory = readDirectorySync(templateDirAbs); + + const processDirectory = (entries: OutputEntry[], output: OutputEntry[]) => { + subTemplates = loadSubTemplates(entries, subTemplates); + + // Generate all files, recurse all directories + for (const dirent of entries) { + if (dirent.type === "File") { + const name = path.parse(dirent.name).name; + + // file templates don't contain '_' + if (name.indexOf("_") === -1) { + const data = Mustache.render(dirent.data, view, subTemplates); + + // If the file isn't empty, add it to the output + if (data) { + output.push({ + type: "File", + name: name.replace("-", "."), + data, + }); + } + } + } else if (dirent.type === "Directory" && subDirectories) { + const subOutput: OutputEntry[] = []; + + processDirectory(dirent.data as OutputEntry[], subOutput); + + output.push({ + type: "Directory", + name: dirent.name, + data: subOutput, + }); + } + } + }; + + processDirectory(directory.entries, output); + + return output; +} + +export function loadSubTemplates( + entries: OutputEntry[], + existingSubTemplates?: Record +): Record { + const subTemplates: Record = existingSubTemplates + ? existingSubTemplates + : {}; + + for (const file of entries) { + if (file.type !== "File") { + continue; + } + + const name = path.parse(file.name).name; + + // sub-templates contain '_' in their file names + if (name.indexOf("_") > -1) { + subTemplates[name] = file.data as string; + } + } + + return subTemplates; +} diff --git a/packages/schema/bind/src/types.ts b/packages/schema/bind/src/types.ts index 8f0c9d51a0..cf892c6f76 100644 --- a/packages/schema/bind/src/types.ts +++ b/packages/schema/bind/src/types.ts @@ -23,7 +23,8 @@ export interface BindModuleOptions { } export interface BindOptions { - bindLanguage: BindLanguage; modules: BindModuleOptions[]; + projectName: string; + bindLanguage: BindLanguage; commonDirAbs?: string; } diff --git a/packages/schema/compose/src/index.ts b/packages/schema/compose/src/index.ts index 46a7f7b4f0..c04fa0a648 100644 --- a/packages/schema/compose/src/index.ts +++ b/packages/schema/compose/src/index.ts @@ -1,5 +1,4 @@ import { - schemaKinds, SchemaKind, SchemaInfos, SchemaInfo, @@ -12,6 +11,7 @@ import { renderSchema } from "./render"; import { TypeInfo, combineTypeInfo } from "@web3api/schema-parse"; export * from "./types"; +export { renderSchema }; export type ComposerOutput = Partial & Required<{ combined: SchemaInfos["combined"] }>; @@ -38,7 +38,7 @@ export async function composeSchema( throw Error("No schema provided"); } - for (const kind of schemaKinds) { + for (const kind of Object.keys(schemas)) { const schema = schemas[kind]; if (schema === undefined) { @@ -65,7 +65,7 @@ export async function composeSchema( typeInfo: includeTypeInfo ? typeInfo : undefined, }); - for (const kind of schemaKinds) { + for (const kind of Object.keys(typeInfos)) { const typeInfo = typeInfos[kind]; if (typeInfo) { output[kind] = createSchemaInfo(typeInfo); diff --git a/packages/schema/compose/src/resolve.ts b/packages/schema/compose/src/resolve.ts index 2fb7664e85..c4d55ba974 100644 --- a/packages/schema/compose/src/resolve.ts +++ b/packages/schema/compose/src/resolve.ts @@ -472,12 +472,7 @@ function addModuleImportsDirective( return result.replace(typeCapture, replacementModuleStr); }; - if (schemaKind === "plugin") { - result = modifySchema(false); - result = modifySchema(true); - } else { - result = modifySchema(schemaKind === "mutation"); - } + result = modifySchema(schemaKind === "mutation"); return result; } @@ -1081,7 +1076,7 @@ export function resolveEnvTypes( return; } - const isMutationEnv = schemaKind === "mutation" || schemaKind === "plugin"; + const isMutationEnv = schemaKind === "mutation"; const moduleEnvDef = isMutationEnv ? typeInfo.envTypes.mutation diff --git a/packages/schema/compose/src/types.ts b/packages/schema/compose/src/types.ts index b4bd7e6f5a..9fd5dec429 100644 --- a/packages/schema/compose/src/types.ts +++ b/packages/schema/compose/src/types.ts @@ -5,9 +5,7 @@ export interface SchemaFile { absolutePath: string; } -export const schemaKinds = ["query", "mutation", "plugin", "combined"] as const; - -export type SchemaKind = typeof schemaKinds[number]; +export type SchemaKind = "combined" | string; export interface SchemaInfo { schema?: string; diff --git a/packages/schema/parse/src/__tests__/validate-env.spec.ts b/packages/schema/parse/src/__tests__/validate-env.spec.ts index 15f8af7e52..ab7dd58749 100644 --- a/packages/schema/parse/src/__tests__/validate-env.spec.ts +++ b/packages/schema/parse/src/__tests__/validate-env.spec.ts @@ -45,7 +45,7 @@ type QueryEnv { } type Query { - sanitizeQueryEnv(prop: String): String + sanitizeEnv(prop: String): String } ` @@ -59,7 +59,7 @@ type QueryEnv { } type Query { - sanitizeQueryEnv(env: QueryClientEnv): String + sanitizeEnv(env: QueryClientEnv): String } ` @@ -97,7 +97,7 @@ type MutationEnv { } type Mutation { - sanitizeMutationEnv(prop: String): String + sanitizeEnv(prop: String): String } ` @@ -111,7 +111,7 @@ type MutationEnv { } type Mutation { - sanitizeMutationEnv(env: MutationClientEnv): String + sanitizeEnv(env: MutationClientEnv): String } ` @@ -133,35 +133,35 @@ describe("Web3API Schema Environment Validation", () => { it("throws error if sanitize environment method invalid", () => { expect(exec(missingQuery)).toThrow( - /Must have 'sanitizeQueryEnv' method inside module methods when using 'QueryClientEnv'/gm + /validateClientEnvironment: Cannot find the specified module type by name 'Query' while trying to validate 'QueryClientEnv'/gm ); expect(exec(missingMutation)).toThrow( - /Must have 'sanitizeMutationEnv' method inside module methods when using 'MutationClientEnv'/gm + /validateClientEnvironment: Cannot find the specified module type by name 'Mutation' while trying to validate 'MutationClientEnv'/gm ); expect(exec(missingQuerySanitizeEnvironment)).toThrow( - /Must have 'sanitizeQueryEnv' method inside module methods when using 'QueryClientEnv'/gm + /Must have 'sanitizeEnv' method inside module methods when using 'QueryClientEnv'/gm ); expect(exec(missingMutationSanitizeEnvironment)).toThrow( - /Must have 'sanitizeMutationEnv' method inside module methods when using 'MutationClientEnv'/gm + /Must have 'sanitizeEnv' method inside module methods when using 'MutationClientEnv'/gm ); expect(exec(invalidQuerySanitizeEnvironmentArguments)).toThrow( - /'sanitizeQueryEnv' module method should have single argument 'env: QueryClientEnv'/gm + /'sanitizeEnv' module method should have single argument 'env: QueryClientEnv'/gm ); expect(exec(invalidMutationSanitizeEnviromentArguments)).toThrow( - /'sanitizeMutationEnv' module method should have single argument 'env: MutationClientEnv'/gm + /'sanitizeEnv' module method should have single argument 'env: MutationClientEnv'/gm ); expect(exec(invalidQuerySanitizeEnvironmentReturnType)).toThrow( - /'sanitizeQueryEnv' module method should have required return type 'QueryEnv'/gm + /'sanitizeEnv' module method should have required return type 'QueryEnv'/gm ); expect(exec(invalidMutationSanitizeEnvironmentReturnType)).toThrow( - /'sanitizeMutationEnv' module method should have required return type 'MutationEnv'/gm + /'sanitizeEnv' module method should have required return type 'MutationEnv'/gm ); }); }); diff --git a/packages/schema/parse/src/validate/env.ts b/packages/schema/parse/src/validate/env.ts index fe8ee28e61..ab85f0a57a 100644 --- a/packages/schema/parse/src/validate/env.ts +++ b/packages/schema/parse/src/validate/env.ts @@ -6,7 +6,6 @@ export function validateEnv(info: TypeInfo): void { info, "Query", info.envTypes.query.client, - "sanitizeQueryEnv", info.envTypes.query.sanitized ); } @@ -16,7 +15,6 @@ export function validateEnv(info: TypeInfo): void { info, "Mutation", info.envTypes.mutation.client, - "sanitizeMutationEnv", info.envTypes.mutation.sanitized ); } @@ -26,7 +24,6 @@ export function validateClientEnvironment( info: TypeInfo, module: "Mutation" | "Query", client: ObjectDefinition, - sanitizeMethod: "sanitizeQueryEnv" | "sanitizeMutationEnv", sanitized?: ObjectDefinition ): void { if (!sanitized) { @@ -38,16 +35,16 @@ export function validateClientEnvironment( const moduleObject = info.moduleTypes.find((type) => type.type === module); if (!moduleObject) { throw new Error( - `Must have '${sanitizeMethod}' method inside module methods when using '${client.type}'` + `validateClientEnvironment: Cannot find the specified module type by name '${module}' while trying to validate '${client.type}'` ); } const sanitizeEnvMethod = moduleObject.methods.find( - (method) => method.name === sanitizeMethod + (method) => method.name === "sanitizeEnv" ); if (!sanitizeEnvMethod) { throw new Error( - `Must have '${sanitizeMethod}' method inside module methods when using '${client.type}'` + `Must have 'sanitizeEnv' method inside module methods when using '${client.type}'` ); } @@ -59,7 +56,7 @@ export function validateClientEnvironment( sanitizeEnvMethod.arguments[0].required === false ) { throw new Error( - `'${sanitizeMethod}' module method should have single argument 'env: ${client.type}'` + `'sanitizeEnv' module method should have single argument 'env: ${client.type}'` ); } @@ -69,7 +66,7 @@ export function validateClientEnvironment( sanitizeEnvMethod.return.required === false ) { throw new Error( - `'${sanitizeMethod}' module method should have required return type '${sanitized.type}'` + `'sanitizeEnv' module method should have required return type '${sanitized.type}'` ); } } diff --git a/packages/schema/parse/src/validate/types.ts b/packages/schema/parse/src/validate/types.ts index 4ce62090a2..3ff62ed7ca 100644 --- a/packages/schema/parse/src/validate/types.ts +++ b/packages/schema/parse/src/validate/types.ts @@ -134,10 +134,7 @@ export const getPropertyTypesValidator = (): SchemaValidator => { } }, FieldDefinition: (node) => { - if ( - node.name.value === "sanitizeMutationEnv" || - node.name.value === "sanitizeQueryEnv" - ) { + if (node.name.value === "sanitizeEnv") { return; } diff --git a/packages/templates/api/assemblyscript/scripts/deploy-contract.js b/packages/templates/api/assemblyscript/scripts/deploy-contract.js index 7fadb07222..e4eb8e2b12 100644 --- a/packages/templates/api/assemblyscript/scripts/deploy-contract.js +++ b/packages/templates/api/assemblyscript/scripts/deploy-contract.js @@ -22,7 +22,7 @@ async function main() { }, }); - const address = await eth.deployContract({ + const address = await eth.getModules().mutation.deployContract({ abi: contractAbi.abi, bytecode: contractAbi.bytecode, args: [], diff --git a/packages/templates/plugin/typescript/package.json b/packages/templates/plugin/typescript/package.json index 6b510eca8c..8f5701f245 100644 --- a/packages/templates/plugin/typescript/package.json +++ b/packages/templates/plugin/typescript/package.json @@ -5,8 +5,8 @@ "version": "0.0.1-prealpha.71", "main": "build/index.js", "scripts": { - "build": "rimraf ./build && tsc --project tsconfig.json", - "prebuild": "npx w3 plugin codegen", + "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.json", + "codegen": "npx w3 plugin codegen", "test": "jest --passWithNoTests --runInBand --verbose", "test:ci": "jest --passWithNoTests --runInBand --verbose", "test:watch": "jest --watch --passWithNoTests --verbose" diff --git a/packages/templates/plugin/typescript/src/__tests__/e2e.spec.ts b/packages/templates/plugin/typescript/src/__tests__/e2e.spec.ts index 2cc48245de..a5f7a7e6be 100644 --- a/packages/templates/plugin/typescript/src/__tests__/e2e.spec.ts +++ b/packages/templates/plugin/typescript/src/__tests__/e2e.spec.ts @@ -12,25 +12,30 @@ describe("e2e", () => { plugins: [ { uri: uri, - plugin: samplePlugin({ defaultValue: "foo bar" }) + plugin: samplePlugin({ + query: { + defaultValue: "foo bar" + }, + mutation: { } + }) } ] }); }); it("sampleQuery", async () => { - const result = await client.query({ + const result = await client.invoke({ uri, - query: `query { - sampleQuery( - data: "fuz baz " - ) - }` + module: "query", + method: "sampleQuery", + input: { + data: "fuz baz " + }, }); - expect(result.errors).toBeFalsy(); + expect(result.error).toBeFalsy(); expect(result.data).toBeTruthy(); - expect(result.data?.sampleQuery).toBe("fuz baz foo bar"); + expect(result.data).toBe("fuz baz foo bar"); }); it("sampleMutation", async () => { diff --git a/packages/templates/plugin/typescript/src/index.ts b/packages/templates/plugin/typescript/src/index.ts index cfc392c521..b455821d3e 100644 --- a/packages/templates/plugin/typescript/src/index.ts +++ b/packages/templates/plugin/typescript/src/index.ts @@ -1,49 +1,3 @@ -import { mutation, query } from "./resolvers"; -import { manifest } from "./w3"; +// TIP: All user-defined code lives in the module folders (./query, ./mutation) -import { - Plugin, - PluginFactory, - PluginPackageManifest, - PluginModules, -} from "@web3api/core-js"; - -export interface SamplePluginConfig { - defaultValue: string; -} - -export class SamplePlugin extends Plugin { - constructor(private _config: SamplePluginConfig) { - super(); - } - - public static manifest(): PluginPackageManifest { - return manifest; - } - - public getModules(): PluginModules { - return { - query: query(this), - mutation: mutation(this), - }; - } - - public async sampleQuery(data: string): Promise { - return data + this._config.defaultValue; - } - - public sampleMutation(data: Uint8Array): boolean { - return data.length > 0; - } -} - -export const samplePlugin: PluginFactory = ( - opts: SamplePluginConfig -) => { - return { - factory: () => new SamplePlugin(opts), - manifest: SamplePlugin.manifest(), - }; -}; - -export const plugin = samplePlugin; +export * from "./w3"; diff --git a/packages/templates/plugin/typescript/src/mutation/index.ts b/packages/templates/plugin/typescript/src/mutation/index.ts new file mode 100644 index 0000000000..6eba47468e --- /dev/null +++ b/packages/templates/plugin/typescript/src/mutation/index.ts @@ -0,0 +1,14 @@ +import { + Client, + Module, + Input_sampleMutation, +} from "./w3"; + +export interface MutationConfig extends Record { } + +export class Mutation extends Module { + + public sampleMutation(input: Input_sampleMutation, client: Client): boolean { + return input.data.length > 0; + } +} diff --git a/packages/templates/plugin/typescript/schema.graphql b/packages/templates/plugin/typescript/src/mutation/schema.graphql similarity index 52% rename from packages/templates/plugin/typescript/schema.graphql rename to packages/templates/plugin/typescript/src/mutation/schema.graphql index 1a01b12787..358bcbd6eb 100644 --- a/packages/templates/plugin/typescript/schema.graphql +++ b/packages/templates/plugin/typescript/src/mutation/schema.graphql @@ -1,7 +1,3 @@ -type Query { - sampleQuery(data: String!): String! -} - type Mutation { sampleMutation(data: Bytes!): Boolean! } diff --git a/packages/templates/plugin/typescript/src/query/index.ts b/packages/templates/plugin/typescript/src/query/index.ts new file mode 100644 index 0000000000..aadf3804cd --- /dev/null +++ b/packages/templates/plugin/typescript/src/query/index.ts @@ -0,0 +1,16 @@ +import { + Client, + Module, + Input_sampleQuery, +} from "./w3"; + +export interface QueryConfig extends Record { + defaultValue: string; +} + +export class Query extends Module { + + public async sampleQuery(input: Input_sampleQuery, client: Client): Promise { + return input.data + this.config.defaultValue; + } +} diff --git a/packages/templates/plugin/typescript/src/query/schema.graphql b/packages/templates/plugin/typescript/src/query/schema.graphql new file mode 100644 index 0000000000..f8e6a89462 --- /dev/null +++ b/packages/templates/plugin/typescript/src/query/schema.graphql @@ -0,0 +1,3 @@ +type Query { + sampleQuery(data: String!): String! +} diff --git a/packages/templates/plugin/typescript/src/resolvers.ts b/packages/templates/plugin/typescript/src/resolvers.ts deleted file mode 100644 index 94ad6349ea..0000000000 --- a/packages/templates/plugin/typescript/src/resolvers.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { SamplePlugin } from "."; -import { Query, Mutation } from "./w3"; - -export const query = (plugin: SamplePlugin): Query.Module => ({ - sampleQuery: async (input: Query.Input_sampleQuery) => { - return await plugin.sampleQuery(input.data); - }, -}); - -export const mutation = (plugin: SamplePlugin): Mutation.Module => ({ - sampleMutation: (input: Mutation.Input_sampleMutation) => { - return plugin.sampleMutation(input.data); - }, -}); diff --git a/packages/templates/plugin/typescript/web3api.plugin.yaml b/packages/templates/plugin/typescript/web3api.plugin.yaml index b21359a846..2b3f62bb66 100644 --- a/packages/templates/plugin/typescript/web3api.plugin.yaml +++ b/packages/templates/plugin/typescript/web3api.plugin.yaml @@ -1,3 +1,10 @@ -format: 0.0.1-prealpha.1 +format: 0.0.1-prealpha.2 +name: Sample language: plugin/typescript -schema: ./schema.graphql +modules: + query: + schema: ./src/query/schema.graphql + module: ./src/query/index.ts + mutation: + schema: ./src/mutation/schema.graphql + module: ./src/mutation/index.ts diff --git a/packages/test-cases/cases/apis/env-client-types/mutation/index.ts b/packages/test-cases/cases/apis/env-client-types/mutation/index.ts index 6e589854b6..95af49b271 100644 --- a/packages/test-cases/cases/apis/env-client-types/mutation/index.ts +++ b/packages/test-cases/cases/apis/env-client-types/mutation/index.ts @@ -1,7 +1,7 @@ import { env, Input_mutEnvironment, - Input_sanitizeMutationEnv, + Input_sanitizeEnv, MutationEnv } from "./w3"; @@ -9,7 +9,7 @@ export function mutEnvironment(input: Input_mutEnvironment): MutationEnv { return env as MutationEnv; } -export function sanitizeMutationEnv(input: Input_sanitizeMutationEnv): MutationEnv { +export function sanitizeEnv(input: Input_sanitizeEnv): MutationEnv { return { str: input.env.str, optStr: input.env.optStr, diff --git a/packages/test-cases/cases/apis/env-client-types/mutation/schema.graphql b/packages/test-cases/cases/apis/env-client-types/mutation/schema.graphql index bf0b599fcd..c562be486e 100644 --- a/packages/test-cases/cases/apis/env-client-types/mutation/schema.graphql +++ b/packages/test-cases/cases/apis/env-client-types/mutation/schema.graphql @@ -1,5 +1,5 @@ type Mutation { - sanitizeMutationEnv(env: MutationClientEnv!): MutationEnv! + sanitizeEnv(env: MutationClientEnv!): MutationEnv! mutEnvironment(arg: String!): MutationEnv } diff --git a/packages/test-cases/cases/apis/env-client-types/query/index.ts b/packages/test-cases/cases/apis/env-client-types/query/index.ts index 6f79bf0aeb..65d7f146e9 100644 --- a/packages/test-cases/cases/apis/env-client-types/query/index.ts +++ b/packages/test-cases/cases/apis/env-client-types/query/index.ts @@ -1,7 +1,7 @@ import { env, Input_environment, - Input_sanitizeQueryEnv, + Input_sanitizeEnv, QueryEnv } from "./w3"; @@ -9,7 +9,7 @@ export function environment(input: Input_environment): QueryEnv { return env as QueryEnv; } -export function sanitizeQueryEnv(input: Input_sanitizeQueryEnv): QueryEnv { +export function sanitizeEnv(input: Input_sanitizeEnv): QueryEnv { return { str: input.env.str, optStr: input.env.optStr, diff --git a/packages/test-cases/cases/apis/env-client-types/query/schema.graphql b/packages/test-cases/cases/apis/env-client-types/query/schema.graphql index 3b6d68ecbb..26090443a4 100644 --- a/packages/test-cases/cases/apis/env-client-types/query/schema.graphql +++ b/packages/test-cases/cases/apis/env-client-types/query/schema.graphql @@ -1,5 +1,5 @@ type Query { - sanitizeQueryEnv(env: QueryClientEnv!): QueryEnv! + sanitizeEnv(env: QueryClientEnv!): QueryEnv! environment(arg: String!): QueryEnv } diff --git a/packages/test-cases/cases/bind/sanity/input/web3api.meta.yaml b/packages/test-cases/cases/bind/sanity/input/web3api.meta.yaml new file mode 100644 index 0000000000..4b52426697 --- /dev/null +++ b/packages/test-cases/cases/bind/sanity/input/web3api.meta.yaml @@ -0,0 +1,15 @@ +format: 0.0.1-prealpha.1 +name: Mock +subtext: mock subtext +description: mock description +repository: https://github.com/mock/mock +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/bind/sanity/input/web3api.plugin.yaml b/packages/test-cases/cases/bind/sanity/input/web3api.plugin.yaml new file mode 100644 index 0000000000..e54109b444 --- /dev/null +++ b/packages/test-cases/cases/bind/sanity/input/web3api.plugin.yaml @@ -0,0 +1,11 @@ +format: 0.0.1-prealpha.2 +language: plugin/typescript +entrypoint: ./src +meta: ./web3api.meta.yaml +modules: + mutation: + schema: ./mutation/schema.graphql + module: ./mutation/index.ts + query: + schema: ./query/schema.graphql + module: ./query/index.ts \ No newline at end of file diff --git a/packages/test-cases/cases/bind/sanity/output/app-ts/combined/types.ts b/packages/test-cases/cases/bind/sanity/output/app-ts/combined/types.ts index 8c0bf58cc2..f7a52f3463 100644 --- a/packages/test-cases/cases/bind/sanity/output/app-ts/combined/types.ts +++ b/packages/test-cases/cases/bind/sanity/output/app-ts/combined/types.ts @@ -1,6 +1,7 @@ -// @ts-noCheck +// @ts-ignore import * as Types from "./"; +// @ts-ignore import { Client, InvokeApiResult @@ -22,35 +23,35 @@ export type String = string; export type Boolean = boolean; export interface CustomType { - str: String; - optStr?: String | null; - u: UInt; - optU?: UInt | null; - u8: UInt8; - u16: UInt16; - u32: UInt32; - i: Int; - i8: Int8; - i16: Int16; - i32: Int32; - bigint: BigInt; - optBigint?: BigInt | null; - bignumber: BigNumber; - optBignumber?: BigNumber | null; + str: Types.String; + optStr?: Types.String | null; + u: Types.UInt; + optU?: Types.UInt | null; + u8: Types.UInt8; + u16: Types.UInt16; + u32: Types.UInt32; + i: Types.Int; + i8: Types.Int8; + i16: Types.Int16; + i32: Types.Int32; + bigint: Types.BigInt; + optBigint?: Types.BigInt | null; + bignumber: Types.BigNumber; + optBignumber?: Types.BigNumber | null; json: Json; optJson?: Json | null; - bytes: Bytes; - optBytes?: Bytes | null; - boolean: Boolean; - optBoolean?: Boolean | null; - uArray: Array; - uOptArray?: Array | null; - optUOptArray?: Array | null; - optStrOptArray?: Array | null; - uArrayArray: Array>; - uOptArrayOptArray: Array | null>; - uArrayOptArrayArray: Array> | null>; - crazyArray?: Array | null>> | null> | null; + bytes: Types.Bytes; + optBytes?: Types.Bytes | null; + boolean: Types.Boolean; + optBoolean?: Types.Boolean | null; + uArray: Array; + uOptArray?: Array | null; + optUOptArray?: Array | null; + optStrOptArray?: Array | null; + uArrayArray: Array>; + uOptArrayOptArray: Array | null>; + uArrayOptArrayArray: Array> | null>; + crazyArray?: Array | null>> | null> | null; object: Types.AnotherType; optObject?: Types.AnotherType | null; objectArray: Array; @@ -62,9 +63,9 @@ export interface CustomType { } export interface AnotherType { - prop?: String | null; + prop?: Types.String | null; circular?: Types.CustomType | null; - const?: String | null; + const?: Types.String | null; } export enum CustomEnumEnum { @@ -94,7 +95,7 @@ export interface TestImport_Object { /* URI: "testimport.uri.eth" */ export interface TestImport_AnotherObject { - prop: String; + prop: Types.String; } /// Imported Objects END /// @@ -119,11 +120,11 @@ export type TestImport_Enum = TestImport_EnumEnum | TestImport_EnumString; /* URI: "testimport.uri.eth" */ interface TestImport_Query_Input_importedMethod extends Record { - str: String; - optStr?: String | null; - u: UInt; - optU?: UInt | null; - uArrayArray: Array | null>; + str: Types.String; + optStr?: Types.String | null; + u: Types.UInt; + optU?: Types.UInt | null; + uArrayArray: Array | null>; object: Types.TestImport_Object; optObject?: Types.TestImport_Object | null; objectArray: Array; @@ -136,7 +137,7 @@ interface TestImport_Query_Input_importedMethod extends Record /* URI: "testimport.uri.eth" */ interface TestImport_Query_Input_anotherMethod extends Record { - arg: Array; + arg: Array; } /* URI: "testimport.uri.eth" */ @@ -158,8 +159,8 @@ export const TestImport_Query = { input: TestImport_Query_Input_anotherMethod, client: Client, uri: string = "testimport.uri.eth" - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri, module: "query", method: "anotherMethod", @@ -170,14 +171,14 @@ export const TestImport_Query = { /* URI: "testimport.uri.eth" */ interface TestImport_Mutation_Input_importedMethod extends Record { - str: String; + str: Types.String; object: Types.TestImport_Object; objectArray: Array; } /* URI: "testimport.uri.eth" */ interface TestImport_Mutation_Input_anotherMethod extends Record { - arg: Array; + arg: Array; } /* URI: "testimport.uri.eth" */ @@ -199,8 +200,8 @@ export const TestImport_Mutation = { input: TestImport_Mutation_Input_anotherMethod, client: Client, uri: string = "testimport.uri.eth" - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri, module: "mutation", method: "anotherMethod", diff --git a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/index.ts b/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/index.ts deleted file mode 100644 index 905246e513..0000000000 --- a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * as Query from "./query"; -export * as Mutation from "./mutation"; -export * from "./types"; -export * from "./schema"; -export * from "./manifest"; diff --git a/packages/test-cases/cases/bind/sanity/output/plugin-ts/common/index.ts b/packages/test-cases/cases/bind/sanity/output/plugin-ts/common/index.ts new file mode 100644 index 0000000000..6c0a9a1500 --- /dev/null +++ b/packages/test-cases/cases/bind/sanity/output/plugin-ts/common/index.ts @@ -0,0 +1,6 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export * from "./schema"; +export * from "./manifest"; +export * from "./plugin"; diff --git a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/manifest.ts b/packages/test-cases/cases/bind/sanity/output/plugin-ts/common/manifest.ts similarity index 51% rename from packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/manifest.ts rename to packages/test-cases/cases/bind/sanity/output/plugin-ts/common/manifest.ts index 5e193c285e..4d35c2182f 100644 --- a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/manifest.ts +++ b/packages/test-cases/cases/bind/sanity/output/plugin-ts/common/manifest.ts @@ -1,10 +1,15 @@ -// @ts-noCheck +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +/* eslint-disable @typescript-eslint/no-unused-vars */ + import { schema } from "./"; +// @ts-ignore import { PluginPackageManifest, Uri } from "@web3api/core-js"; export const manifest: PluginPackageManifest = { schema, implements: [ ], -} +}; diff --git a/packages/test-cases/cases/bind/sanity/output/plugin-ts/common/plugin.ts b/packages/test-cases/cases/bind/sanity/output/plugin-ts/common/plugin.ts new file mode 100644 index 0000000000..c80ecb8e65 --- /dev/null +++ b/packages/test-cases/cases/bind/sanity/output/plugin-ts/common/plugin.ts @@ -0,0 +1,43 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +import { + Plugin, + PluginFactory, + PluginPackageManifest, + PluginModules, +} from "@web3api/core-js"; +import { Query, QueryConfig } from "../query"; +import { Mutation, MutationConfig } from "../mutation"; +import { manifest } from "./manifest"; + +export interface TestCasePluginConfigs { + query: QueryConfig; + mutation: MutationConfig; +} + +export class TestCasePlugin implements Plugin { + constructor(private _configs: TestCasePluginConfigs) { } + + public static manifest(): PluginPackageManifest { + return manifest; + } + + public getModules(): PluginModules { + return { + query: new Query(this._configs.query), + mutation: new Mutation(this._configs.mutation), + }; + } +} + +export const testCasePlugin: PluginFactory = ( + opts: TestCasePluginConfigs +) => { + return { + factory: () => new TestCasePlugin(opts), + manifest: manifest, + }; +}; + +export const plugin = testCasePlugin; diff --git a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/schema.ts b/packages/test-cases/cases/bind/sanity/output/plugin-ts/common/schema.ts similarity index 98% rename from packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/schema.ts rename to packages/test-cases/cases/bind/sanity/output/plugin-ts/common/schema.ts index 8a25ac0a19..6d121f342c 100644 --- a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/schema.ts +++ b/packages/test-cases/cases/bind/sanity/output/plugin-ts/common/schema.ts @@ -1,3 +1,6 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + export const schema: string = `### Web3API Header START ### scalar UInt scalar UInt8 diff --git a/packages/test-cases/cases/bind/sanity/output/plugin-ts/mutation/index.ts b/packages/test-cases/cases/bind/sanity/output/plugin-ts/mutation/index.ts new file mode 100644 index 0000000000..efe3c2530f --- /dev/null +++ b/packages/test-cases/cases/bind/sanity/output/plugin-ts/mutation/index.ts @@ -0,0 +1,7 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/client-js"; diff --git a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/mutation.ts b/packages/test-cases/cases/bind/sanity/output/plugin-ts/mutation/module.ts similarity index 67% rename from packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/mutation.ts rename to packages/test-cases/cases/bind/sanity/output/plugin-ts/mutation/module.ts index ab9aac71d9..194c2abc63 100644 --- a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/mutation.ts +++ b/packages/test-cases/cases/bind/sanity/output/plugin-ts/mutation/module.ts @@ -1,20 +1,6 @@ -// @ts-noCheck -import { - UInt, - UInt8, - UInt16, - UInt32, - Int, - Int8, - Int16, - Int32, - Bytes, - BigInt, - BigNumber, - Json, - String, - Boolean -} from "./types"; +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + import * as Types from "./types"; import { @@ -24,8 +10,8 @@ import { } from "@web3api/core-js"; export interface Input_mutationMethod extends Record { - str: String; - optStr?: String | null; + str: Types.String; + optStr?: Types.String | null; en: Types.CustomEnum; optEnum?: Types.CustomEnum | null; enumArray: Array; @@ -39,13 +25,19 @@ export interface Input_objectMethod extends Record { optObjectArray?: Array | null; } -export interface Module extends PluginModule { - mutationMethod( +export abstract class Module< + TConfig extends Record +> extends PluginModule< + TConfig, + Types.MutationEnv +> { + + abstract mutationMethod( input: Input_mutationMethod, client: Client - ): MaybeAsync; + ): MaybeAsync; - objectMethod( + abstract objectMethod( input: Input_objectMethod, client: Client ): MaybeAsync; diff --git a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/types.ts b/packages/test-cases/cases/bind/sanity/output/plugin-ts/mutation/types.ts similarity index 66% rename from packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/types.ts rename to packages/test-cases/cases/bind/sanity/output/plugin-ts/mutation/types.ts index edd2ab084d..928d64e218 100644 --- a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/types.ts +++ b/packages/test-cases/cases/bind/sanity/output/plugin-ts/mutation/types.ts @@ -1,6 +1,10 @@ -// @ts-noCheck +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +// @ts-ignore import * as Types from "./"; +// @ts-ignore import { Client, InvokeApiResult @@ -21,49 +25,51 @@ export type Json = string; export type String = string; export type Boolean = boolean; -export interface QueryEnv { - queryProp: String; - optMap?: Map | null; - prop: String; - optProp?: String | null; +/// Envs START /// +export interface MutationEnv extends Record { + mutProp: Types.String; + prop: Types.String; + optProp?: Types.String | null; } +/// Envs END /// -export interface MutationEnv { - mutProp: String; - prop: String; - optProp?: String | null; +/// Objects START /// +export interface AnotherType { + prop?: Types.String | null; + circular?: Types.CustomType | null; + const?: Types.String | null; } export interface CustomType { - str: String; - optStr?: String | null; - u: UInt; - optU?: UInt | null; - u8: UInt8; - u16: UInt16; - u32: UInt32; - i: Int; - i8: Int8; - i16: Int16; - i32: Int32; - bigint: BigInt; - optBigint?: BigInt | null; - bignumber: BigNumber; - optBignumber?: BigNumber | null; + str: Types.String; + optStr?: Types.String | null; + u: Types.UInt; + optU?: Types.UInt | null; + u8: Types.UInt8; + u16: Types.UInt16; + u32: Types.UInt32; + i: Types.Int; + i8: Types.Int8; + i16: Types.Int16; + i32: Types.Int32; + bigint: Types.BigInt; + optBigint?: Types.BigInt | null; + bignumber: Types.BigNumber; + optBignumber?: Types.BigNumber | null; json: Json; optJson?: Json | null; - bytes: Bytes; - optBytes?: Bytes | null; - boolean: Boolean; - optBoolean?: Boolean | null; - uArray: Array; - uOptArray?: Array | null; - optUOptArray?: Array | null; - optStrOptArray?: Array | null; - uArrayArray: Array>; - uOptArrayOptArray: Array | null>; - uArrayOptArrayArray: Array> | null>; - crazyArray?: Array | null>> | null> | null; + bytes: Types.Bytes; + optBytes?: Types.Bytes | null; + boolean: Types.Boolean; + optBoolean?: Types.Boolean | null; + uArray: Array; + uOptArray?: Array | null; + optUOptArray?: Array | null; + optStrOptArray?: Array | null; + uArrayArray: Array>; + uOptArrayOptArray: Array | null>; + uArrayOptArrayArray: Array> | null>; + crazyArray?: Array | null>> | null> | null; object: Types.AnotherType; optObject?: Types.AnotherType | null; objectArray: Array; @@ -74,12 +80,9 @@ export interface CustomType { optEnumArray?: Array | null; } -export interface AnotherType { - prop?: String | null; - circular?: Types.CustomType | null; - const?: String | null; -} +/// Objects END /// +/// Enums START /// export enum CustomEnumEnum { STRING, BYTES, @@ -91,6 +94,8 @@ export type CustomEnumString = export type CustomEnum = CustomEnumEnum | CustomEnumString; +/// Enums END /// + /// Imported Objects START /// /* URI: "testimport.uri.eth" */ @@ -107,13 +112,9 @@ export interface TestImport_Object { /* URI: "testimport.uri.eth" */ export interface TestImport_AnotherObject { - prop: String; + prop: Types.String; } -/// Imported Objects END /// - -/// Imported Enums START /// - /* URI: "testimport.uri.eth" */ export enum TestImport_EnumEnum { STRING, @@ -126,17 +127,17 @@ export type TestImport_EnumString = export type TestImport_Enum = TestImport_EnumEnum | TestImport_EnumString; -/// Imported Enums END /// +/// Imported Objects END /// /// Imported Queries START /// /* URI: "testimport.uri.eth" */ interface TestImport_Query_Input_importedMethod extends Record { - str: String; - optStr?: String | null; - u: UInt; - optU?: UInt | null; - uArrayArray: Array | null>; + str: Types.String; + optStr?: Types.String | null; + u: Types.UInt; + optU?: Types.UInt | null; + uArrayArray: Array | null>; object: Types.TestImport_Object; optObject?: Types.TestImport_Object | null; objectArray: Array; @@ -149,34 +150,29 @@ interface TestImport_Query_Input_importedMethod extends Record /* URI: "testimport.uri.eth" */ interface TestImport_Query_Input_anotherMethod extends Record { - arg: Array; + arg: Array; } /* URI: "testimport.uri.eth" */ -export class TestImport_Query { - public static interfaceUri: string = "testimport.uri.eth"; - - constructor(public uri: string) { - } - - public async importedMethod ( +export const TestImport_Query = { + importedMethod: async ( input: TestImport_Query_Input_importedMethod, client: Client - ): Promise> { + ): Promise> => { return client.invoke({ - uri: this.uri, + uri: "testimport.uri.eth", module: "query", method: "importedMethod", input }); }, - public async anotherMethod ( + anotherMethod: async ( input: TestImport_Query_Input_anotherMethod, client: Client - ): Promise> { - return client.invoke({ - uri: this.uri, + ): Promise> => { + return client.invoke({ + uri: "testimport.uri.eth", module: "query", method: "anotherMethod", input @@ -184,17 +180,16 @@ export class TestImport_Query { } } - /* URI: "testimport.uri.eth" */ interface TestImport_Mutation_Input_importedMethod extends Record { - str: String; + str: Types.String; object: Types.TestImport_Object; objectArray: Array; } /* URI: "testimport.uri.eth" */ interface TestImport_Mutation_Input_anotherMethod extends Record { - arg: Array; + arg: Array; } /* URI: "testimport.uri.eth" */ @@ -214,8 +209,8 @@ export const TestImport_Mutation = { anotherMethod: async ( input: TestImport_Mutation_Input_anotherMethod, client: Client - ): Promise> => { - return client.invoke({ + ): Promise> => { + return client.invoke({ uri: "testimport.uri.eth", module: "mutation", method: "anotherMethod", @@ -224,13 +219,4 @@ export const TestImport_Mutation = { } } - /// Imported Queries END /// - -export class TestImport { - static uri: string = "testimport.uri.eth"; - - public static getImplementations(client: Client): string[] { - return client.getImplementations(this.uri, {}); - } -} diff --git a/packages/test-cases/cases/bind/sanity/output/plugin-ts/query/index.ts b/packages/test-cases/cases/bind/sanity/output/plugin-ts/query/index.ts new file mode 100644 index 0000000000..efe3c2530f --- /dev/null +++ b/packages/test-cases/cases/bind/sanity/output/plugin-ts/query/index.ts @@ -0,0 +1,7 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +export * from "./module"; +export * from "./types"; + +export { Client } from "@web3api/client-js"; diff --git a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/query.ts b/packages/test-cases/cases/bind/sanity/output/plugin-ts/query/module.ts similarity index 65% rename from packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/query.ts rename to packages/test-cases/cases/bind/sanity/output/plugin-ts/query/module.ts index 7d3d9710b6..27e96d642a 100644 --- a/packages/test-cases/cases/bind/sanity/output/plugin-ts/combined/query.ts +++ b/packages/test-cases/cases/bind/sanity/output/plugin-ts/query/module.ts @@ -1,20 +1,6 @@ -// @ts-noCheck -import { - UInt, - UInt8, - UInt16, - UInt32, - Int, - Int8, - Int16, - Int32, - Bytes, - BigInt, - BigNumber, - Json, - String, - Boolean -} from "./types"; +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + import * as Types from "./types"; import { @@ -24,13 +10,13 @@ import { } from "@web3api/core-js"; export interface Input_queryMethod extends Record { - str: String; - optStr?: String | null; + str: Types.String; + optStr?: Types.String | null; en: Types.CustomEnum; optEnum?: Types.CustomEnum | null; enumArray: Array; optEnumArray?: Array | null; - map: Map; + map: Map; } export interface Input_objectMethod extends Record { @@ -40,13 +26,19 @@ export interface Input_objectMethod extends Record { optObjectArray?: Array | null; } -export interface Module extends PluginModule { - queryMethod( +export abstract class Module< + TConfig extends Record +> extends PluginModule< + TConfig, + Types.QueryEnv +> { + + abstract queryMethod( input: Input_queryMethod, client: Client - ): MaybeAsync; + ): MaybeAsync; - objectMethod( + abstract objectMethod( input: Input_objectMethod, client: Client ): MaybeAsync; diff --git a/packages/test-cases/cases/bind/sanity/output/plugin-ts/query/types.ts b/packages/test-cases/cases/bind/sanity/output/plugin-ts/query/types.ts new file mode 100644 index 0000000000..16f6a52c17 --- /dev/null +++ b/packages/test-cases/cases/bind/sanity/output/plugin-ts/query/types.ts @@ -0,0 +1,197 @@ +/// NOTE: This is an auto-generated file. +/// All modifications will be overwritten. + +// @ts-ignore +import * as Types from "./"; + +// @ts-ignore +import { + Client, + InvokeApiResult +} from "@web3api/core-js"; + +export type UInt = number; +export type UInt8 = number; +export type UInt16 = number; +export type UInt32 = number; +export type Int = number; +export type Int8 = number; +export type Int16 = number; +export type Int32 = number; +export type Bytes = Uint8Array; +export type BigInt = string; +export type BigNumber = string; +export type Json = string; +export type String = string; +export type Boolean = boolean; + +/// Envs START /// +export interface QueryEnv extends Record { + queryProp: Types.String; + optMap?: Map | null; + prop: Types.String; + optProp?: Types.String | null; +} +/// Envs END /// + +/// Objects START /// +export interface CustomType { + str: Types.String; + optStr?: Types.String | null; + u: Types.UInt; + optU?: Types.UInt | null; + u8: Types.UInt8; + u16: Types.UInt16; + u32: Types.UInt32; + i: Types.Int; + i8: Types.Int8; + i16: Types.Int16; + i32: Types.Int32; + bigint: Types.BigInt; + optBigint?: Types.BigInt | null; + bignumber: Types.BigNumber; + optBignumber?: Types.BigNumber | null; + json: Json; + optJson?: Json | null; + bytes: Types.Bytes; + optBytes?: Types.Bytes | null; + boolean: Types.Boolean; + optBoolean?: Types.Boolean | null; + uArray: Array; + uOptArray?: Array | null; + optUOptArray?: Array | null; + optStrOptArray?: Array | null; + uArrayArray: Array>; + uOptArrayOptArray: Array | null>; + uArrayOptArrayArray: Array> | null>; + crazyArray?: Array | null>> | null> | null; + object: Types.AnotherType; + optObject?: Types.AnotherType | null; + objectArray: Array; + optObjectArray?: Array | null; + en: Types.CustomEnum; + optEnum?: Types.CustomEnum | null; + enumArray: Array; + optEnumArray?: Array | null; +} + +export interface AnotherType { + prop?: Types.String | null; + circular?: Types.CustomType | null; + const?: Types.String | null; +} + +/// Objects END /// + +/// Enums START /// +export enum CustomEnumEnum { + STRING, + BYTES, +} + +export type CustomEnumString = + | "STRING" + | "BYTES" + +export type CustomEnum = CustomEnumEnum | CustomEnumString; + +/// Enums END /// + +/// Imported Objects START /// + +/* URI: "testimport.uri.eth" */ +export interface TestImport_Object { + object: Types.TestImport_AnotherObject; + optObject?: Types.TestImport_AnotherObject | null; + objectArray: Array; + optObjectArray?: Array | null; + en: Types.TestImport_Enum; + optEnum?: Types.TestImport_Enum | null; + enumArray: Array; + optEnumArray?: Array | null; +} + +/* URI: "testimport.uri.eth" */ +export interface TestImport_AnotherObject { + prop: Types.String; +} + +/* URI: "testimport.uri.eth" */ +export enum TestImport_EnumEnum { + STRING, + BYTES, +} + +export type TestImport_EnumString = + | "STRING" + | "BYTES" + +export type TestImport_Enum = TestImport_EnumEnum | TestImport_EnumString; + +/// Imported Objects END /// + +/// Imported Queries START /// + +/* URI: "testimport.uri.eth" */ +interface TestImport_Query_Input_importedMethod extends Record { + str: Types.String; + optStr?: Types.String | null; + u: Types.UInt; + optU?: Types.UInt | null; + uArrayArray: Array | null>; + object: Types.TestImport_Object; + optObject?: Types.TestImport_Object | null; + objectArray: Array; + optObjectArray?: Array | null; + en: Types.TestImport_Enum; + optEnum?: Types.TestImport_Enum | null; + enumArray: Array; + optEnumArray?: Array | null; +} + +/* URI: "testimport.uri.eth" */ +interface TestImport_Query_Input_anotherMethod extends Record { + arg: Array; +} + +/* URI: "testimport.uri.eth" */ +export class TestImport_Query { + public static interfaceUri: string = "testimport.uri.eth"; + + constructor(public uri: string) { + } + + public async importedMethod ( + input: TestImport_Query_Input_importedMethod, + client: Client + ): Promise> { + return client.invoke({ + uri: this.uri, + module: "query", + method: "importedMethod", + input + }); + } + + public async anotherMethod ( + input: TestImport_Query_Input_anotherMethod, + client: Client + ): Promise> { + return client.invoke({ + uri: this.uri, + module: "query", + method: "anotherMethod", + input + }); + } +} + +/// Imported Queries END /// + +export class TestImport { + static uri: string = "testimport.uri.eth"; + + public static getImplementations(client: Client): string[] { + return client.getImplementations(this.uri, {}); + } +} diff --git a/packages/test-cases/cases/parse/sanity/input.graphql b/packages/test-cases/cases/parse/sanity/input.graphql index 9d31adfff9..ff7865d31b 100644 --- a/packages/test-cases/cases/parse/sanity/input.graphql +++ b/packages/test-cases/cases/parse/sanity/input.graphql @@ -129,7 +129,7 @@ type MutationClientEnv { } type Mutation { - sanitizeMutationEnv(env: MutationClientEnv!): MutationEnv! + sanitizeEnv(env: MutationClientEnv!): MutationEnv! } """ @@ -155,7 +155,7 @@ type Query implements Interface_Query @imports( uri: "testimport.uri.eth", namespace: "TestImport", ) { - sanitizeQueryEnv(env: QueryClientEnv!): QueryEnv! + sanitizeEnv(env: QueryClientEnv!): QueryEnv! """ queryMethod comment """ diff --git a/packages/test-cases/cases/parse/sanity/output.ts b/packages/test-cases/cases/parse/sanity/output.ts index be08525a32..c405b42c94 100644 --- a/packages/test-cases/cases/parse/sanity/output.ts +++ b/packages/test-cases/cases/parse/sanity/output.ts @@ -469,20 +469,10 @@ export const typeInfo: TypeInfo = { { ...createMethodDefinition({ type: "mutation", - name: "sanitizeMutationEnv", - return: createObjectPropertyDefinition({ - name: "sanitizeMutationEnv", - type: "MutationEnv", - required: true, - }), - arguments: [ - createObjectPropertyDefinition({ - name: "env", - type: "MutationClientEnv", - required: true, - }), - ], - }), + name: "sanitizeEnv", + return: createObjectPropertyDefinition({ name: "sanitizeEnv", type: "MutationEnv", required: true }), + arguments: [createObjectPropertyDefinition({ name: "env", type: "MutationClientEnv", required: true })], + }) }, ], }, @@ -499,20 +489,10 @@ export const typeInfo: TypeInfo = { { ...createMethodDefinition({ type: "query", - name: "sanitizeQueryEnv", - return: createObjectPropertyDefinition({ - name: "sanitizeQueryEnv", - type: "QueryEnv", - required: true, - }), - arguments: [ - createObjectPropertyDefinition({ - name: "env", - type: "QueryClientEnv", - required: true, - }), - ], - }), + name: "sanitizeEnv", + return: createObjectPropertyDefinition({ name: "sanitizeEnv", type: "QueryEnv", required: true }), + arguments: [createObjectPropertyDefinition({ name: "env", type: "QueryClientEnv", required: true })], + }) }, { ...createMethodDefinition({ diff --git a/yarn.lock b/yarn.lock index 3ad782d55b..4123690975 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19,13 +19,6 @@ call-me-maybe "^1.0.1" js-yaml "^4.1.0" -"@ardatan/aggregate-error@0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/@ardatan/aggregate-error/-/aggregate-error-0.0.6.tgz#fe6924771ea40fc98dc7a7045c2e872dc8527609" - integrity sha512-vyrkEHG1jrukmzTPtyWB4NLPauUw5bQeg4uhn8f+1SSynmrOcyvlb1GKQjjgoBzElLdfXCRYX8UnBlhklOHYRQ== - dependencies: - tslib "~2.0.1" - "@as-covers/assembly@^0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@as-covers/assembly/-/assembly-0.2.0.tgz#6f335834483ddf91b21da06955bd86647f9e8db9" @@ -206,7 +199,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.7.2", "@babel/generator@^7.9.0": +"@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== @@ -289,7 +282,7 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.16.7", "@babel/helper-function-name@^7.17.9": +"@babel/helper-function-name@^7.16.7", "@babel/helper-function-name@^7.17.9": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== @@ -378,14 +371,14 @@ dependencies: "@babel/types" "^7.16.0" -"@babel/helper-split-export-declaration@^7.12.13", "@babel/helper-split-export-declaration@^7.16.7": +"@babel/helper-split-export-declaration@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== dependencies: "@babel/types" "^7.16.7" -"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.16.7": +"@babel/helper-validator-identifier@^7.16.7": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== @@ -423,12 +416,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@7.12.16": - version "7.12.16" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.16.tgz#cc31257419d2c3189d394081635703f549fc1ed4" - integrity sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw== - -"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.9", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.7.0", "@babel/parser@^7.9.0": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.9", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.7.0", "@babel/parser@^7.9.0": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.9.tgz#9c94189a6062f0291418ca021077983058e171ef" integrity sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg== @@ -1418,21 +1406,6 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/traverse@7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.13.tgz#689f0e4b4c08587ad26622832632735fb8c4e0c0" - integrity sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA== - dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.12.13" - "@babel/helper-function-name" "^7.12.13" - "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/parser" "^7.12.13" - "@babel/types" "^7.12.13" - debug "^4.1.0" - 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.7.2", "@babel/traverse@^7.9.0": version "7.17.9" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d" @@ -1449,16 +1422,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.13.tgz#8be1aa8f2c876da11a9cf650c0ecf656913ad611" - integrity sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - -"@babel/types@^7.0.0", "@babel/types@^7.12.13", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.9.0": +"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0", "@babel/types@^7.9.0": version "7.17.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== @@ -1533,16 +1497,6 @@ is-absolute "^1.0.0" is-negated-glob "^1.0.0" -"@endemolshinegroup/cosmiconfig-typescript-loader@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz#eea4635828dde372838b0909693ebd9aafeec22d" - integrity sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA== - dependencies: - lodash.get "^4" - make-error "^1" - ts-node "^9" - tslib "^2" - "@ensdomains/ens@0.4.4": version "0.4.4" resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.4.tgz#05e7bb138471a5e5844b4c1f263ec0ad7edcd272" @@ -1593,9 +1547,9 @@ "@ethersproject/strings" ">=5.0.0-beta.130" "@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== + 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" @@ -1660,6 +1614,14 @@ dependencies: "@ethersproject/bytes" "^5.6.0" +"@ethersproject/basex@5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.0.7.tgz#2f7026b12c9dee6cdc7b7bf1805461836e635495" + integrity sha512-OsXnRsujGmYD9LYyJlX+cVe5KfwgLUbUJrJMWdzRWogrygXd5HvGd7ygX1AYjlu1z8W/+t2FoQnczDR/H2iBjA== + dependencies: + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/properties" "^5.0.7" + "@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" @@ -1677,7 +1639,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.6.0": +"@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== @@ -1772,9 +1734,9 @@ integrity sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg== "@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== + 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" @@ -1786,7 +1748,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.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== @@ -1819,9 +1781,9 @@ ws "7.2.3" "@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== + 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" @@ -2036,209 +1998,6 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== -"@graphql-eslint/eslint-plugin@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@graphql-eslint/eslint-plugin/-/eslint-plugin-1.0.1.tgz#f633c6a85630e536e9fe9c4bbbc7d3b4bfae5105" - integrity sha512-+7nOx36ZgP57iL4tUbMTmILasqaL9FeYiH8G+/Co7mY871OmHNIS91izHaAZHh28emCE6dW/J1Wt9dhmag/OUw== - dependencies: - "@graphql-tools/code-file-loader" "~6.3.0" - "@graphql-tools/graphql-file-loader" "~6.2.0" - "@graphql-tools/graphql-tag-pluck" "~6.5.0" - "@graphql-tools/json-file-loader" "~6.2.6" - "@graphql-tools/load" "~6.2.0" - "@graphql-tools/url-loader" "~6.10.0" - "@graphql-tools/utils" "~7.10.0" - graphql-config "^3.2.0" - graphql-depth-limit "1.1.0" - -"@graphql-tools/batch-execute@^7.1.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@graphql-tools/batch-execute/-/batch-execute-7.1.2.tgz#35ba09a1e0f80f34f1ce111d23c40f039d4403a0" - integrity sha512-IuR2SB2MnC2ztA/XeTMTfWcA0Wy7ZH5u+nDkDNLAdX+AaSyDnsQS35sCmHqG0VOGTl7rzoyBWLCKGwSJplgtwg== - dependencies: - "@graphql-tools/utils" "^7.7.0" - dataloader "2.0.0" - tslib "~2.2.0" - value-or-promise "1.0.6" - -"@graphql-tools/code-file-loader@~6.3.0": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@graphql-tools/code-file-loader/-/code-file-loader-6.3.1.tgz#42dfd4db5b968acdb453382f172ec684fa0c34ed" - integrity sha512-ZJimcm2ig+avgsEOWWVvAaxZrXXhiiSZyYYOJi0hk9wh5BxZcLUNKkTp6EFnZE/jmGUwuos3pIjUD3Hwi3Bwhg== - dependencies: - "@graphql-tools/graphql-tag-pluck" "^6.5.1" - "@graphql-tools/utils" "^7.0.0" - tslib "~2.1.0" - -"@graphql-tools/delegate@^7.0.1", "@graphql-tools/delegate@^7.1.5": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@graphql-tools/delegate/-/delegate-7.1.5.tgz#0b027819b7047eff29bacbd5032e34a3d64bd093" - integrity sha512-bQu+hDd37e+FZ0CQGEEczmRSfQRnnXeUxI/0miDV+NV/zCbEdIJj5tYFNrKT03W6wgdqx8U06d8L23LxvGri/g== - dependencies: - "@ardatan/aggregate-error" "0.0.6" - "@graphql-tools/batch-execute" "^7.1.2" - "@graphql-tools/schema" "^7.1.5" - "@graphql-tools/utils" "^7.7.1" - dataloader "2.0.0" - tslib "~2.2.0" - value-or-promise "1.0.6" - -"@graphql-tools/graphql-file-loader@^6.0.0", "@graphql-tools/graphql-file-loader@~6.2.0": - version "6.2.7" - resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-file-loader/-/graphql-file-loader-6.2.7.tgz#d3720f2c4f4bb90eb2a03a7869a780c61945e143" - integrity sha512-5k2SNz0W87tDcymhEMZMkd6/vs6QawDyjQXWtqkuLTBF3vxjxPD1I4dwHoxgWPIjjANhXybvulD7E+St/7s9TQ== - dependencies: - "@graphql-tools/import" "^6.2.6" - "@graphql-tools/utils" "^7.0.0" - tslib "~2.1.0" - -"@graphql-tools/graphql-tag-pluck@^6.5.1", "@graphql-tools/graphql-tag-pluck@~6.5.0": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-6.5.1.tgz#5fb227dbb1e19f4b037792b50f646f16a2d4c686" - integrity sha512-7qkm82iFmcpb8M6/yRgzjShtW6Qu2OlCSZp8uatA3J0eMl87TxyJoUmL3M3UMMOSundAK8GmoyNVFUrueueV5Q== - dependencies: - "@babel/parser" "7.12.16" - "@babel/traverse" "7.12.13" - "@babel/types" "7.12.13" - "@graphql-tools/utils" "^7.0.0" - tslib "~2.1.0" - -"@graphql-tools/import@^6.2.6": - version "6.6.10" - resolved "https://registry.yarnpkg.com/@graphql-tools/import/-/import-6.6.10.tgz#b77d19c8e5b6d376c517aa16f959b14197840669" - integrity sha512-yHdlEPTvIjrngtQFNgkMQJt/DjG3hQKvc6Mb8kaatFV4yERN5zx+0vpdrwxTwRNG1N7bI/YCkbrc7PXOb+g89Q== - dependencies: - "@graphql-tools/utils" "8.6.6" - resolve-from "5.0.0" - tslib "~2.3.0" - -"@graphql-tools/json-file-loader@^6.0.0", "@graphql-tools/json-file-loader@~6.2.6": - version "6.2.6" - resolved "https://registry.yarnpkg.com/@graphql-tools/json-file-loader/-/json-file-loader-6.2.6.tgz#830482cfd3721a0799cbf2fe5b09959d9332739a" - integrity sha512-CnfwBSY5926zyb6fkDBHnlTblHnHI4hoBALFYXnrg0Ev4yWU8B04DZl/pBRUc459VNgO2x8/mxGIZj2hPJG1EA== - dependencies: - "@graphql-tools/utils" "^7.0.0" - tslib "~2.0.1" - -"@graphql-tools/load@^6.0.0", "@graphql-tools/load@~6.2.0": - version "6.2.8" - resolved "https://registry.yarnpkg.com/@graphql-tools/load/-/load-6.2.8.tgz#16900fb6e75e1d075cad8f7ea439b334feb0b96a" - integrity sha512-JpbyXOXd8fJXdBh2ta0Q4w8ia6uK5FHzrTNmcvYBvflFuWly2LDTk2abbSl81zKkzswQMEd2UIYghXELRg8eTA== - dependencies: - "@graphql-tools/merge" "^6.2.12" - "@graphql-tools/utils" "^7.5.0" - globby "11.0.3" - import-from "3.0.0" - is-glob "4.0.1" - p-limit "3.1.0" - tslib "~2.2.0" - unixify "1.0.0" - valid-url "1.0.9" - -"@graphql-tools/merge@6.0.0 - 6.2.14": - version "6.2.14" - resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-6.2.14.tgz#694e2a2785ba47558e5665687feddd2935e9d94e" - integrity sha512-RWT4Td0ROJai2eR66NHejgf8UwnXJqZxXgDWDI+7hua5vNA2OW8Mf9K1Wav1ZkjWnuRp4ztNtkZGie5ISw55ow== - dependencies: - "@graphql-tools/schema" "^7.0.0" - "@graphql-tools/utils" "^7.7.0" - tslib "~2.2.0" - -"@graphql-tools/merge@8.2.7": - version "8.2.7" - resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.7.tgz#add05bcc47df6b7390f31acbcadd986e160d58f9" - integrity sha512-rKxjNogqu1UYAG/y5FOb6lJsmSQbWA+jq4inWjNEVX54VGGE7/WGnmPaqcsyomNOfS3vIRS6NnG+DxiQSqetjg== - dependencies: - "@graphql-tools/utils" "8.6.6" - tslib "~2.3.0" - -"@graphql-tools/merge@^6.2.12": - version "6.2.17" - resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-6.2.17.tgz#4dedf87d8435a5e1091d7cc8d4f371ed1e029f1f" - integrity sha512-G5YrOew39fZf16VIrc49q3c8dBqQDD0ax5LYPiNja00xsXDi0T9zsEWVt06ApjtSdSF6HDddlu5S12QjeN8Tow== - dependencies: - "@graphql-tools/schema" "^8.0.2" - "@graphql-tools/utils" "8.0.2" - tslib "~2.3.0" - -"@graphql-tools/schema@^7.0.0", "@graphql-tools/schema@^7.1.5": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-7.1.5.tgz#07b24e52b182e736a6b77c829fc48b84d89aa711" - integrity sha512-uyn3HSNSckf4mvQSq0Q07CPaVZMNFCYEVxroApOaw802m9DcZPgf9XVPy/gda5GWj9AhbijfRYVTZQgHnJ4CXA== - dependencies: - "@graphql-tools/utils" "^7.1.2" - tslib "~2.2.0" - value-or-promise "1.0.6" - -"@graphql-tools/schema@^8.0.2": - version "8.3.7" - resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.7.tgz#6e2be8e17a1f97f4d11d5b787c414ec29400fde2" - integrity sha512-7byr9J6rfMPFPfiR4u65dy20xHATTvbgOY7KYd1sYPnMKKfRZe0tUgpnE+noXcfob7N8s366WaVh7bEoztQMwg== - dependencies: - "@graphql-tools/merge" "8.2.7" - "@graphql-tools/utils" "8.6.6" - tslib "~2.3.0" - value-or-promise "1.0.11" - -"@graphql-tools/url-loader@^6.0.0", "@graphql-tools/url-loader@~6.10.0": - version "6.10.1" - resolved "https://registry.yarnpkg.com/@graphql-tools/url-loader/-/url-loader-6.10.1.tgz#dc741e4299e0e7ddf435eba50a1f713b3e763b33" - integrity sha512-DSDrbhQIv7fheQ60pfDpGD256ixUQIR6Hhf9Z5bRjVkXOCvO5XrkwoWLiU7iHL81GB1r0Ba31bf+sl+D4nyyfw== - dependencies: - "@graphql-tools/delegate" "^7.0.1" - "@graphql-tools/utils" "^7.9.0" - "@graphql-tools/wrap" "^7.0.4" - "@microsoft/fetch-event-source" "2.0.1" - "@types/websocket" "1.0.2" - abort-controller "3.0.0" - cross-fetch "3.1.4" - extract-files "9.0.0" - form-data "4.0.0" - graphql-ws "^4.4.1" - is-promise "4.0.0" - isomorphic-ws "4.0.1" - lodash "4.17.21" - meros "1.1.4" - subscriptions-transport-ws "^0.9.18" - sync-fetch "0.3.0" - tslib "~2.2.0" - valid-url "1.0.9" - ws "7.4.5" - -"@graphql-tools/utils@8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.0.2.tgz#795a8383cdfdc89855707d62491c576f439f3c51" - integrity sha512-gzkavMOgbhnwkHJYg32Adv6f+LxjbQmmbdD5Hty0+CWxvaiuJq+nU6tzb/7VSU4cwhbNLx/lGu2jbCPEW1McZQ== - dependencies: - tslib "~2.3.0" - -"@graphql-tools/utils@8.6.6": - version "8.6.6" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.6.6.tgz#f7c88d32818b748f3e3867ed87a562769b544417" - integrity sha512-wjY2ljKLCnnbRrDNPPgPNqCujou0LFSOWcxAjV6DYUlfFWTsAEvlYmsmY4T+K12wI/fnqoJ2bUwIlap1plFDMg== - dependencies: - tslib "~2.3.0" - -"@graphql-tools/utils@^7.0.0", "@graphql-tools/utils@^7.1.2", "@graphql-tools/utils@^7.5.0", "@graphql-tools/utils@^7.7.0", "@graphql-tools/utils@^7.7.1", "@graphql-tools/utils@^7.8.1", "@graphql-tools/utils@^7.9.0", "@graphql-tools/utils@~7.10.0": - version "7.10.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-7.10.0.tgz#07a4cb5d1bec1ff1dc1d47a935919ee6abd38699" - integrity sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w== - dependencies: - "@ardatan/aggregate-error" "0.0.6" - camel-case "4.1.2" - tslib "~2.2.0" - -"@graphql-tools/wrap@^7.0.4": - version "7.0.8" - resolved "https://registry.yarnpkg.com/@graphql-tools/wrap/-/wrap-7.0.8.tgz#ad41e487135ca3ea1ae0ea04bb3f596177fb4f50" - integrity sha512-1NDUymworsOlb53Qfh7fonDi2STvqCtbeE68ntKY9K/Ju/be2ZNxrFSbrBHwnxWcN9PjISNnLcAyJ1L5tCUyhg== - dependencies: - "@graphql-tools/delegate" "^7.1.5" - "@graphql-tools/schema" "^7.1.5" - "@graphql-tools/utils" "^7.8.1" - tslib "~2.2.0" - value-or-promise "1.0.6" - "@hapi/address@2.x.x": version "2.1.4" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" @@ -2276,11 +2035,6 @@ resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== -"@iarna/toml@^2.2.5": - version "2.2.5" - resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c" - integrity sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg== - "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -2806,9 +2560,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.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" @@ -3489,11 +3243,6 @@ npmlog "^4.1.2" write-file-atomic "^3.0.3" -"@microsoft/fetch-event-source@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz#9ceecc94b49fbaa15666e38ae8587f64acce007d" - integrity sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA== - "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -4082,9 +3831,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" @@ -4222,10 +3971,15 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= +"@types/lodash@4.14.178": + version "4.14.178" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8" + integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw== + "@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" @@ -4243,9 +3997,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" @@ -4263,9 +4017,9 @@ 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" @@ -4285,9 +4039,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" @@ -4314,9 +4068,9 @@ "@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" "*" @@ -4370,13 +4124,6 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f" integrity sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ== -"@types/websocket@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.2.tgz#d2855c6a312b7da73ed16ba6781815bf30c6187a" - integrity sha512-B5m9aq7cbbD/5/jThEr33nUY8WEfVi6A2YKCTOvw5Ldy7mtsOkqRvGjnzy6g7iMMDsgu7xREuCzqATLDLQVKcQ== - dependencies: - "@types/node" "*" - "@types/yargs-parser@*": version "21.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" @@ -4724,9 +4471,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" @@ -5195,13 +4942,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" @@ -5213,16 +4961,11 @@ arrify@^2.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== -as-bigint@0.5.3: +as-bigint@0.5.3, as-bigint@^0.5.1: version "0.5.3" resolved "https://registry.yarnpkg.com/as-bigint/-/as-bigint-0.5.3.tgz#a0647d0b7ce835077aca33115e71eb26a83df8be" integrity sha512-tg9iTO/vPeovOM5CSk1WxYcsfBd/cd3twhBW5PrpcGUfiSEXlPB69eOxFKvSbZnpuDxBAyQ4YBgEkfnYL89Czw== -as-bigint@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/as-bigint/-/as-bigint-0.5.1.tgz#c14c381bf816798bbda35a8080a8085d036f72f1" - integrity sha512-1yFnss/Xz6ii69fK8uVWyZim/+ybgQWX98r8mqIfgs5MFEQaI+PkHtIDWZOwb8k0ASuZx0VQVvgnYtVo+/eMtg== - as-bignumber@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/as-bignumber/-/as-bignumber-0.2.0.tgz#13feb2e5054c8a2d557618de2e507af39cfb7532" @@ -5340,9 +5083,9 @@ 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" @@ -6120,11 +5863,6 @@ babylon@^6.18.0: resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== -backo2@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" - integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= - balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -6484,7 +6222,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== @@ -6564,7 +6302,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.0.5, buffer@^5.2.1, buffer@^5.4.3, buffer@^5.5.0, buffer@^5.6.0, buffer@^5.7.0: +buffer@^5.0.5, buffer@^5.2.1, buffer@^5.4.3, buffer@^5.5.0, buffer@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -6766,7 +6504,7 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camel-case@4.1.2, camel-case@^4.1.1: +camel-case@^4.1.1: version "4.1.2" resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== @@ -6824,9 +6562,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.30001327" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001327.tgz#c1546d7d7bb66506f0ccdad6a7d07fc6d668c858" - integrity sha512-1/Cg4jlD9qjZzhbzkzEaAC2JHsP0WrOc8Rd/3a3LuajGzGWR/hD7TVyvq99VqmTy99eVh8Zkmdq213OgvgXx7w== + 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" @@ -7609,17 +7347,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.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.1.tgz#47b9c5e79efbf13935f637449fa1cdec8cd9515f" + integrity sha512-CWbNqTluLMvZg1cjsQUbGiCM91dobSHKfDIyCoxuqxthdjGuUlaMbCsSehP3CBiVvG0C7P6UIrC1v0hgFE75jw== 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.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" @@ -7627,9 +7365,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.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" @@ -7649,13 +7387,6 @@ cors@^2.8.1: object-assign "^4" vary "^1" -cosmiconfig-toml-loader@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig-toml-loader/-/cosmiconfig-toml-loader-1.0.0.tgz#0681383651cceff918177debe9084c0d3769509b" - integrity sha512-H/2gurFWVi7xXvCyvsWRLCMekl4tITJcX0QEsDMpzxtuxDyM59xLatYNg4s/k9AA/HdtCYfj2su8mgA0GSDLDA== - dependencies: - "@iarna/toml" "^2.2.5" - cosmiconfig@6.0.0, cosmiconfig@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" @@ -7667,17 +7398,6 @@ cosmiconfig@6.0.0, cosmiconfig@^6.0.0: path-type "^4.0.0" yaml "^1.7.2" -cosmiconfig@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" - integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - cosmiconfig@^5.0.0, cosmiconfig@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" @@ -7749,13 +7469,6 @@ cross-fetch@3.0.5: dependencies: node-fetch "2.6.0" -cross-fetch@3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" - integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ== - dependencies: - node-fetch "2.6.1" - cross-spawn@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" @@ -8098,11 +7811,6 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" -dataloader@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-2.0.0.tgz#41eaf123db115987e21ca93c005cd7753c55fe6f" - integrity sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ== - dateformat@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" @@ -8115,7 +7823,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== @@ -8212,11 +7920,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" @@ -8481,9 +8190,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" @@ -8630,9 +8339,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.106" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.106.tgz#e7a3bfa9d745dd9b9e597616cb17283cc349781a" - integrity sha512-ZYfpVLULm67K7CaaGP7DmjyeMY4naxsbTy+syVVxT6QHI1Ww8XbJjmr9fDckrhq44WzCrcC5kH3zGpdusxwwqg== + version "1.4.115" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.115.tgz#62d68576385f17e9b268b04e98cc132ed04c6671" + integrity sha512-yy1W7cTcreskCWSRTtvp8CNLEci3uYBn5s1U4IytDz7v485iLVPh4QwFuSCavsFbxRLVvwnHNXEFIDShrk/UnQ== elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" @@ -8788,10 +8497,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" @@ -8804,7 +8513,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" @@ -8814,6 +8523,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" @@ -8824,9 +8540,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" @@ -9446,11 +9162,6 @@ eventemitter3@4.0.4: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== -eventemitter3@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" - integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== - eventemitter3@^4.0.0, eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -9732,11 +9443,6 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extract-files@9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-9.0.0.tgz#8a7744f2437f81f5ed3250ed9f1550de902fe54a" - integrity sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ== - extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -9774,7 +9480,7 @@ fast-glob@^2.0.2: merge2 "^1.2.3" micromatch "^3.1.10" -fast-glob@^3.1.1, fast-glob@^3.2.5, fast-glob@^3.2.9: +fast-glob@^3.2.5, fast-glob@^3.2.9: version "3.2.11" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== @@ -10062,15 +9768,6 @@ fork-ts-checker-webpack-plugin@3.1.1: tapable "^1.0.0" worker-rpc "^0.1.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== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@^2.4.0: version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -10251,6 +9948,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.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" resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.12.2.tgz#c0920f7db0d4ac062ffe2375cb004089806f627a" @@ -10508,18 +10210,6 @@ globalthis@^1.0.1: dependencies: define-properties "^1.1.3" -globby@11.0.3: - version "11.0.3" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" - integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - globby@8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.2.tgz#5697619ccd95c5275dbb2d6faa42087c1a941d8d" @@ -10635,30 +10325,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -graphql-config@^3.2.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/graphql-config/-/graphql-config-3.4.1.tgz#59f937a1b4d3a3c2dcdb27ddf5b4d4d4b2c6e9e1" - integrity sha512-g9WyK4JZl1Ko++FSyE5Ir2g66njfxGzrDDhBOwnkoWf/t3TnnZG6BBkWP+pkqVJ5pqMJGPKHNrbew8jRxStjhw== - dependencies: - "@endemolshinegroup/cosmiconfig-typescript-loader" "3.0.2" - "@graphql-tools/graphql-file-loader" "^6.0.0" - "@graphql-tools/json-file-loader" "^6.0.0" - "@graphql-tools/load" "^6.0.0" - "@graphql-tools/merge" "6.0.0 - 6.2.14" - "@graphql-tools/url-loader" "^6.0.0" - "@graphql-tools/utils" "^7.0.0" - cosmiconfig "7.0.0" - cosmiconfig-toml-loader "1.0.0" - minimatch "3.0.4" - string-env-interpolation "1.0.1" - -graphql-depth-limit@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/graphql-depth-limit/-/graphql-depth-limit-1.1.0.tgz#59fe6b2acea0ab30ee7344f4c75df39cc18244e8" - integrity sha512-+3B2BaG8qQ8E18kzk9yiSdAa75i/hnnOwgSeAxVJctGQPvmeiLtqKOYF6HETCyRjiF7Xfsyal0HbLlxCQkgkrw== - dependencies: - arrify "^1.0.1" - graphql-json-transform@^1.1.0-alpha.0: version "1.1.0-alpha.0" resolved "https://registry.yarnpkg.com/graphql-json-transform/-/graphql-json-transform-1.1.0-alpha.0.tgz#fb0c88d24840067e6c55ac64bbc8d4e5de245d2d" @@ -10674,11 +10340,6 @@ graphql-tag@2.11.0: resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.11.0.tgz#1deb53a01c46a7eb401d6cb59dec86fa1cccbffd" integrity sha512-VmsD5pJqWJnQZMUeRwrDhfgoyqcfwEkvtpANqcoUG8/tOLkwNgU9mzub/Mc78OJMhHjx7gfAMTxzdG43VGg3bA== -graphql-ws@^4.4.1: - version "4.9.0" - resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-4.9.0.tgz#5cfd8bb490b35e86583d8322f5d5d099c26e365c" - integrity sha512-sHkK9+lUm20/BGawNEWNtVAeJzhZeBg21VmvmLoT5NdGVeZWv5PdIhkcayQIAgjSyyQ17WMKmbDijIPG2On+Ag== - graphql@15.5.0: version "15.5.0" resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.0.tgz#39d19494dbe69d1ea719915b578bf920344a69d5" @@ -10745,9 +10406,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" @@ -10764,6 +10425,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" @@ -11096,9 +10764,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" @@ -11189,7 +10857,7 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.4, ignore@^5.2.0: +ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== @@ -11222,13 +10890,6 @@ import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" -import-from@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/import-from/-/import-from-3.0.0.tgz#055cfec38cd5a27d8057ca51376d7d3bf0891966" - integrity sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ== - dependencies: - resolve-from "^5.0.0" - import-from@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" @@ -11662,9 +11323,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" @@ -11773,13 +11434,6 @@ is-generator-function@^1.0.7: dependencies: has-tostringtag "^1.0.0" -is-glob@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -11919,11 +11573,6 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== -is-promise@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" - integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ== - is-promise@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" @@ -11964,7 +11613,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== @@ -12103,11 +11752,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isomorphic-ws@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== - isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -12147,9 +11791,9 @@ istanbul-lib-instrument@^4.0.3: semver "^6.3.0" 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== + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== dependencies: "@babel/core" "^7.12.3" "@babel/parser" "^7.14.7" @@ -12291,11 +11935,6 @@ iterable-ndjson@^1.1.0: dependencies: string_decoder "^1.2.0" -iterall@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" - integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== - jaeger-client@^3.15.0: version "3.19.0" resolved "https://registry.yarnpkg.com/jaeger-client/-/jaeger-client-3.19.0.tgz#9b5bd818ebd24e818616ee0f5cffe1722a53ae6e" @@ -14139,11 +13778,6 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -lodash.get@^4: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= - lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" @@ -14264,7 +13898,7 @@ lodash.upperfirst@^4.3.1: resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" integrity sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984= -lodash@4.17.21, lodash@4.x, "lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.7.0: +lodash@4.x, "lodash@>=3.5 <5", lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -14347,11 +13981,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" @@ -14386,7 +14015,7 @@ make-dir@^3.0.0, make-dir@^3.0.2: dependencies: semver "^6.0.0" -make-error@1.x, make-error@^1, make-error@^1.1.1: +make-error@1.x, make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -14607,11 +14236,6 @@ merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -meros@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/meros/-/meros-1.1.4.tgz#c17994d3133db8b23807f62bec7f0cb276cfd948" - integrity sha512-E9ZXfK9iQfG9s73ars9qvvvbSIkJZF5yOo9j4tcwM5tN8mUKfj/EKN5PzOr3ZH0y5wL7dLAHw3RVEfpQV9Q7VQ== - methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -15160,9 +14784,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" @@ -15268,11 +14892,6 @@ node-fetch@2.6.0: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== -node-fetch@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -15386,9 +15005,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" @@ -15661,7 +15280,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== @@ -15983,13 +15602,6 @@ p-is-promise@^2.0.0, p-is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== -p-limit@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -17643,9 +17255,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" @@ -18054,12 +17666,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" @@ -18238,11 +17851,6 @@ resolve-cwd@^3.0.0: dependencies: resolve-from "^5.0.0" -resolve-from@5.0.0, resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -18253,6 +17861,11 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + resolve-url-loader@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz#28931895fa1eab9be0647d3b2958c100ae3c0bf0" @@ -18586,11 +18199,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" @@ -18930,15 +18543,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== @@ -19270,11 +18883,6 @@ strict-uri-encode@^2.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= -string-env-interpolation@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string-env-interpolation/-/string-env-interpolation-1.0.1.tgz#ad4397ae4ac53fe6c91d1402ad6f6a52862c7152" - integrity sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg== - string-length@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" @@ -19512,17 +19120,6 @@ stylehacks@^4.0.0: postcss "^7.0.0" postcss-selector-parser "^3.0.0" -subscriptions-transport-ws@^0.9.18: - version "0.9.19" - resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.19.tgz#10ca32f7e291d5ee8eb728b9c02e43c52606cdcf" - integrity sha512-dxdemxFFB0ppCLg10FTtRqH/31FNRL1y1BQv8209MK5I4CwALb7iihQg+7p65lFcIl8MHatINWBLOqpgU4Kyyw== - dependencies: - backo2 "^1.0.2" - eventemitter3 "^3.1.0" - iterall "^1.2.1" - symbol-observable "^1.0.4" - ws "^5.2.0 || ^6.0.0 || ^7.0.0" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -19617,24 +19214,11 @@ swarm-js@^0.1.40: tar "^4.0.2" xhr-request "^1.0.1" -symbol-observable@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" - integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== - symbol-tree@^3.2.2, symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -sync-fetch@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/sync-fetch/-/sync-fetch-0.3.0.tgz#77246da949389310ad978ab26790bb05f88d1335" - integrity sha512-dJp4qg+x4JwSEW1HibAuMi0IIrBI3wuQr2GimmqB7OXR50wmwzfdusG+p39R9w3R6aFtZ2mzvxvWKQ3Bd/vx3g== - dependencies: - buffer "^5.7.0" - node-fetch "^2.6.1" - table@^5.2.3: version "5.4.6" resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" @@ -20125,18 +19709,6 @@ ts-node@8.10.2: source-map-support "^0.5.17" yn "3.1.1" -ts-node@^9: - version "9.1.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" - integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== - dependencies: - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" - yn "3.1.1" - ts-pnp@1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.6.tgz#389a24396d425a0d3162e96d2b4638900fdc289a" @@ -20162,26 +19734,11 @@ tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@~2.3.0: +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== -tslib@~2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" - integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== - -tslib@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== - -tslib@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" - integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== - tsutils@^3.17.1: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -20311,9 +19868,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" @@ -20463,13 +20020,6 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -unixify@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unixify/-/unixify-1.0.0.tgz#3a641c8c2ffbce4da683a5c70f03a462940c2090" - integrity sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA= - dependencies: - normalize-path "^2.1.1" - unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -20674,9 +20224,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" @@ -20701,11 +20251,6 @@ v8-to-istanbul@^8.1.0: 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" - integrity sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA= - validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -20721,16 +20266,6 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" -value-or-promise@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.11.tgz#3e90299af31dd014fe843fe309cefa7c1d94b140" - integrity sha512-41BrgH+dIbCFXClcSapVs5M6GkENd3gQOJpEfPDNa71LsUGMXDL0jMWpI/Rh7WhX+Aalfz2TTS3Zt5pUsbnhLg== - -value-or-promise@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/value-or-promise/-/value-or-promise-1.0.6.tgz#218aa4794aa2ee24dcf48a29aba4413ed584747f" - integrity sha512-9r0wQsWD8z/BxPOvnwbPf05ZvFngXyouE9EKB+5GbYix+BYnAwrIChCUyFIinfbf2FL/U71z+CPpbnmTdxrwBg== - varint@^5.0.0, varint@^5.0.2, varint@~5.0.0: version "5.0.2" resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" @@ -21704,11 +21239,6 @@ ws@7.3.1: resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== -ws@7.4.5: - version "7.4.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.5.tgz#a484dd851e9beb6fdb420027e3885e8ce48986c1" - integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g== - ws@7.4.6: version "7.4.6" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" @@ -21730,11 +21260,6 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" -"ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.4.6: - version "7.5.7" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" - integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== - ws@^6.1.2, ws@^6.2.1: version "6.2.2" resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" @@ -21742,6 +21267,11 @@ ws@^6.1.2, ws@^6.2.1: dependencies: async-limiter "~1.0.0" +ws@^7.4.6: + version "7.5.7" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" + integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== + xhr-request-promise@^0.1.2: version "0.1.3" resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" @@ -22038,11 +21568,6 @@ yn@3.1.1: resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - zen-observable-ts@^0.8.21: version "0.8.21" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz#85d0031fbbde1eba3cd07d3ba90da241215f421d"