diff --git a/CHANGELOG.md b/CHANGELOG.md index d4ee25c0fa..106b38c082 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# Web3API 0.0.1-prealpha.36 +## Features +* Upgrade all JavaScript plugins to use the new `w3 plugin codegen` command. The command generates typings based on the GraphQL schema of the plugin. This ensures the plugin's resolvers match 1:1 with the GraphQL schema. + # Web3API 0.0.1-prealpha.35 ## Bugs * `@web3api/schema-bind`: Fix TypeScript plugin enum bindings. diff --git a/VERSION b/VERSION index 829ede87c3..c45a9abb43 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.1-prealpha.35 \ No newline at end of file +0.0.1-prealpha.36 \ No newline at end of file diff --git a/package.json b/package.json index d13aafdfd9..1e12889941 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,11 @@ "scripts": { "reset": "yarn clean && yarn && yarn build", "clean": "npx rimraf ./**/node_modules ./**/build ./**/coverage ./**/.w3", - "build": "lerna run build --no-private --ignore @web3api/cli* --ignore @web3api/react && lerna run build --scope @web3api/client-js --scope @web3api/react && lerna run build --scope @web3api/cli", + "build": "yarn build:core && yarn build:plugins && yarn build:client && yarn build:cli", + "build:core": "lerna run build --no-private --ignore @web3api/*-plugin-js --ignore @web3api/cli* --ignore @web3api/react", + "build:plugins": "lerna run build --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 --ignore @web3api/uts46-plugin-js", "lint:fix": "lerna run lint --ignore @web3api/uts46-plugin-js -- --fix", "lint:ci": "yarn lint", diff --git a/packages/cli/src/__tests__/project/invalid-web3api-1.yaml b/packages/cli/src/__tests__/project/invalid-web3api-1.yaml index 44f795db97..87bca4ce8d 100644 --- a/packages/cli/src/__tests__/project/invalid-web3api-1.yaml +++ b/packages/cli/src/__tests__/project/invalid-web3api-1.yaml @@ -13,6 +13,3 @@ query: module: language: wasm/assemblyscript file: ./src/wrong/index.ts -import_redirects: - - uri: w3://ens/ethereum.web3api.eth - schema: ../../../../js/plugins/ethereum/schema.graphql \ No newline at end of file diff --git a/packages/cli/src/__tests__/project/invalid-web3api-2.yaml b/packages/cli/src/__tests__/project/invalid-web3api-2.yaml index dd7170facd..a78cbf3b19 100644 --- a/packages/cli/src/__tests__/project/invalid-web3api-2.yaml +++ b/packages/cli/src/__tests__/project/invalid-web3api-2.yaml @@ -13,6 +13,3 @@ wrong_query: module: language: wasm/assemblyscript file: ./src/query/index.ts -import_redirects: - - uri: w3://ens/ethereum.web3api.eth - schema: ../../../../js/plugins/ethereum/schema.graphql \ No newline at end of file diff --git a/packages/cli/src/__tests__/project/web3api.docker.yaml b/packages/cli/src/__tests__/project/web3api.docker.yaml index 500a79c352..6421985684 100644 --- a/packages/cli/src/__tests__/project/web3api.docker.yaml +++ b/packages/cli/src/__tests__/project/web3api.docker.yaml @@ -9,6 +9,3 @@ modules: query: schema: ./src/query/schema.graphql module: ./src/query/index.ts -import_redirects: - - uri: w3://ens/ethereum.web3api.eth - schema: ../../../../js/plugins/ethereum/schema.graphql diff --git a/packages/cli/src/__tests__/project/web3api.no-docker.yaml b/packages/cli/src/__tests__/project/web3api.no-docker.yaml index 5c285d21d9..0cace01b01 100644 --- a/packages/cli/src/__tests__/project/web3api.no-docker.yaml +++ b/packages/cli/src/__tests__/project/web3api.no-docker.yaml @@ -9,6 +9,3 @@ modules: query: schema: ./src/query/schema.graphql module: ./src/query/index.ts -import_redirects: - - uri: w3://ens/ethereum.web3api.eth - schema: ../../../../js/plugins/ethereum/schema.graphql diff --git a/packages/cli/src/__tests__/project/web3api.wrong-config.yaml b/packages/cli/src/__tests__/project/web3api.wrong-config.yaml index 91dbfe1f88..06056c08b9 100644 --- a/packages/cli/src/__tests__/project/web3api.wrong-config.yaml +++ b/packages/cli/src/__tests__/project/web3api.wrong-config.yaml @@ -9,6 +9,3 @@ modules: query: schema: ./src/query/schema.graphql module: ./src/query/index.ts -import_redirects: - - uri: w3://ens/ethereum.web3api.eth - schema: ../../../../js/plugins/ethereum/schema.graphql diff --git a/packages/cli/src/__tests__/project/web3api.yaml b/packages/cli/src/__tests__/project/web3api.yaml index fbb94c5bdb..05996fffd1 100644 --- a/packages/cli/src/__tests__/project/web3api.yaml +++ b/packages/cli/src/__tests__/project/web3api.yaml @@ -13,6 +13,3 @@ query: module: language: wasm/assemblyscript file: ./src/query/index.ts -import_redirects: - - uri: w3://ens/ethereum.web3api.eth - schema: ../../../../js/plugins/ethereum/schema.graphql \ No newline at end of file diff --git a/packages/js/plugins/ens/package.json b/packages/js/plugins/ens/package.json index 325c55091d..8811d61955 100644 --- a/packages/js/plugins/ens/package.json +++ b/packages/js/plugins/ens/package.json @@ -13,7 +13,8 @@ "schema.graphql" ], "scripts": { - "build": "rimraf ./build && tsc --project tsconfig.build.json", + "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "codegen": "npx -p @web3api/cli w3 plugin codegen", "lint": "eslint --color --ext .ts src/", "test": "jest --passWithNoTests --runInBand --verbose", "test:ci": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/ens/schema.graphql b/packages/js/plugins/ens/schema.graphql index d132e26dea..08ccba9880 100644 --- a/packages/js/plugins/ens/schema.graphql +++ b/packages/js/plugins/ens/schema.graphql @@ -1,4 +1,5 @@ #import { Query, MaybeUriOrManifest } into UriResolver from "ens/uri-resolver.core.web3api.eth" +#import { Query } into Ethereum from "ens/ethereum.web3api.eth" type Query implements UriResolver_Query { tryResolveUri( diff --git a/packages/js/plugins/ens/src/index.ts b/packages/js/plugins/ens/src/index.ts index 2bd3d90a45..6ffaa04a2c 100644 --- a/packages/js/plugins/ens/src/index.ts +++ b/packages/js/plugins/ens/src/index.ts @@ -1,12 +1,11 @@ /* eslint-disable import/no-extraneous-dependencies */ import { query } from "./resolvers"; -import { manifest } from "./manifest"; +import { manifest, Query, Ethereum_Query } from "./w3"; import { Client, Plugin, PluginPackageManifest, - PluginModules, PluginFactory, } from "@web3api/core-js"; import { ethers } from "ethers"; @@ -44,9 +43,11 @@ export class EnsPlugin extends Plugin { return ethers.utils.isValidName(domain) && domain.indexOf(".eth") !== -1; } - // TODO: generated types here from the schema.graphql to ensure safety `Resolvers` - // https://github.com/web3-api/monorepo/issues/101 - public getModules(client: Client): PluginModules { + public getModules( + client: Client + ): { + query: Query.Module; + } { return { query: query(this, client), }; @@ -104,19 +105,8 @@ export class EnsPlugin extends Plugin { args: string[], networkNameOrChainId?: string ): Promise => { - const { data, errors } = await client.query<{ - callContractView: string; - }>({ - uri: "ens/ethereum.web3api.eth", - query: `query { - callContractView( - address: $address, - method: $method, - args: $args, - connection: $connection - ) - }`, - variables: { + const { data, error } = await Ethereum_Query.callContractView( + { address, method, args, @@ -126,24 +116,25 @@ export class EnsPlugin extends Plugin { } : undefined, }, - }); + client + ); - if (errors && errors.length) { - throw errors; + if (error) { + throw error; } - if (data && data.callContractView) { - if (typeof data.callContractView !== "string") { + if (data) { + if (typeof data !== "string") { throw Error( - `Malformed data returned from Ethereum.callContractView: ${data.callContractView}` + `Malformed data returned from Ethereum.callContractView: ${data}` ); } - return data.callContractView; + return data; } throw Error( - `Ethereum.callContractView returned nothing.\nData: ${data}\nErrors: ${errors}` + `Ethereum.callContractView returned nothing.\nData: ${data}\nError: ${error}` ); }; diff --git a/packages/js/plugins/ens/src/manifest.ts b/packages/js/plugins/ens/src/manifest.ts deleted file mode 100644 index a7dbd1f165..0000000000 --- a/packages/js/plugins/ens/src/manifest.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { PluginPackageManifest, coreInterfaceUris } from "@web3api/core-js"; - -export const manifest: PluginPackageManifest = { - // TODO: use the schema.graphql - // https://github.com/web3-api/monorepo/issues/101 - schema: `### Web3API Header START ### -scalar UInt -scalar UInt8 -scalar UInt16 -scalar UInt32 -scalar UInt64 -scalar Int -scalar Int8 -scalar Int16 -scalar Int32 -scalar Int64 -scalar Bytes -scalar BigInt -directive @imported( - uri: String! - namespace: String! - nativeType: String! -) on OBJECT | ENUM -directive @imports( - types: [String!]! -) on OBJECT -### 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: "w3://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: "w3://ens/uri-resolver.core.web3api.eth", - namespace: "UriResolver", - nativeType: "MaybeUriOrManifest" -) { - uri: String - manifest: String -} -### Imported Objects END ### -`, - implements: [coreInterfaceUris.uriResolver], -}; diff --git a/packages/js/plugins/ens/src/resolvers.ts b/packages/js/plugins/ens/src/resolvers.ts index 0882e7b9b3..751bf66658 100644 --- a/packages/js/plugins/ens/src/resolvers.ts +++ b/packages/js/plugins/ens/src/resolvers.ts @@ -1,10 +1,11 @@ import { EnsPlugin } from "./"; +import { Query } from "./w3"; -import { Client, PluginModule } from "@web3api/core-js"; +import { Client } from "@web3api/core-js"; -export const query = (ens: EnsPlugin, client: Client): PluginModule => ({ +export const query = (ens: EnsPlugin, client: Client): Query.Module => ({ // uri-resolver.core.web3api.eth - tryResolveUri: async (input: { authority: string; path: string }) => { + tryResolveUri: async (input: Query.Input_tryResolveUri) => { if (input.authority !== "ens") { return null; } @@ -27,7 +28,7 @@ export const query = (ens: EnsPlugin, client: Client): PluginModule => ({ // Nothing found return { uri: null, manifest: null }; }, - getFile: (_input: { path: string }) => { + getFile: (_input: Query.Input_getFile) => { return null; }, }); diff --git a/packages/js/plugins/ethereum/package.json b/packages/js/plugins/ethereum/package.json index 9baca00300..6108138f99 100644 --- a/packages/js/plugins/ethereum/package.json +++ b/packages/js/plugins/ethereum/package.json @@ -13,7 +13,8 @@ "schema.graphql" ], "scripts": { - "build": "rimraf ./build && tsc --project tsconfig.build.json", + "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "codegen": "npx -p @web3api/cli w3 plugin codegen", "lint": "eslint --color --ext .ts src/", "test": "jest --passWithNoTests --runInBand --verbose", "test:ci": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/ethereum/schema.graphql b/packages/js/plugins/ethereum/schema.graphql index 15c11c537b..a8c54ae8aa 100644 --- a/packages/js/plugins/ethereum/schema.graphql +++ b/packages/js/plugins/ethereum/schema.graphql @@ -1,26 +1,3 @@ -### Web3API Header START ### -scalar UInt -scalar UInt8 -scalar UInt16 -scalar UInt32 -scalar Int -scalar Int8 -scalar Int16 -scalar Int32 -scalar Bytes -scalar BigInt - -directive @imported( - uri: String! - namespace: String! - nativeType: String! -) on OBJECT | ENUM - -directive @imports( - types: [String!]! -) on OBJECT -### Web3API Header END ### - type TxReceipt { to: String! from: String! diff --git a/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts b/packages/js/plugins/ethereum/src/__tests__/e2e.spec.ts index 15994511bc..f767495ebc 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 "../types"; +import * as Schema from "../w3"; import { Web3ApiClient } from "@web3api/client-js"; import { ensPlugin } from "@web3api/ens-plugin-js"; diff --git a/packages/js/plugins/ethereum/src/__tests__/integration/web3api.yaml b/packages/js/plugins/ethereum/src/__tests__/integration/web3api.yaml index 2de39cd323..d62a5fa5a0 100644 --- a/packages/js/plugins/ethereum/src/__tests__/integration/web3api.yaml +++ b/packages/js/plugins/ethereum/src/__tests__/integration/web3api.yaml @@ -13,6 +13,3 @@ query: module: language: wasm/assemblyscript file: ./src/query/index.ts -import_redirects: - - uri: w3://ens/ethereum.web3api.eth - schema: ../../../schema.graphql diff --git a/packages/js/plugins/ethereum/src/index.ts b/packages/js/plugins/ethereum/src/index.ts index 1e999d4e71..997290b9ac 100644 --- a/packages/js/plugins/ethereum/src/index.ts +++ b/packages/js/plugins/ethereum/src/index.ts @@ -1,7 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import { query, mutation } from "./resolvers"; -import { manifest } from "./manifest"; -import * as Schema from "./types"; +import { manifest, Query, Mutation } from "./w3"; +import * as Types from "./w3"; import { Address, AccountIndex, @@ -18,7 +18,6 @@ import { Client, Plugin, PluginPackageManifest, - PluginModules, PluginFactory, } from "@web3api/core-js"; import { ethers } from "ethers"; @@ -67,9 +66,12 @@ export class EthereumPlugin extends Plugin { return manifest; } - // TODO: generated types here from the schema.graphql to ensure safety `Resolvers` - // https://github.com/web3-api/monorepo/issues/101 - public getModules(_client: Client): PluginModules { + public getModules( + _client: Client + ): { + query: Query.Module; + mutation: Mutation.Module; + } { return { query: query(this), mutation: mutation(this), @@ -79,41 +81,43 @@ export class EthereumPlugin extends Plugin { /// Mutation public async callContractMethod( - input: Schema.Input_callContractMethod - ): Promise { + input: Mutation.Input_callContractMethod + ): Promise { const res = await this._callContractMethod(input); return Mapping.toTxResponse(res); } public async callContractMethodAndWait( - input: Schema.Input_callContractMethodAndWait - ): Promise { + input: Mutation.Input_callContractMethodAndWait + ): Promise { const response = await this._callContractMethod(input); const res = await response.wait(); return Mapping.toTxReceipt(res); } public async sendTransaction( - input: Schema.Input_sendTransaction - ): Promise { + input: Mutation.Input_sendTransaction + ): Promise { const connection = await this.getConnection(input.connection); const signer = connection.getSigner(); - const res = await signer.sendTransaction(input.tx); + const res = await signer.sendTransaction(Mapping.fromTxRequest(input.tx)); return Mapping.toTxResponse(res); } public async sendTransactionAndWait( - input: Schema.Input_sendTransactionAndWait - ): Promise { + input: Mutation.Input_sendTransactionAndWait + ): Promise { const connection = await this.getConnection(input.connection); const signer = connection.getSigner(); - const response = await signer.sendTransaction(input.tx); + const response = await signer.sendTransaction( + Mapping.fromTxRequest(input.tx) + ); const receipt = await response.wait(); return Mapping.toTxReceipt(receipt); } public async deployContract( - input: Schema.Input_deployContract + input: Mutation.Input_deployContract ): Promise { const connection = await this.getConnection(input.connection); const signer = connection.getSigner(); @@ -128,14 +132,14 @@ export class EthereumPlugin extends Plugin { return contract.address; } - public async signMessage(input: Schema.Input_signMessage): Promise { + public async signMessage(input: Mutation.Input_signMessage): Promise { const connection = await this.getConnection(input.connection); const messageHash = ethers.utils.id(input.message); const messageHashBytes = ethers.utils.arrayify(messageHash); return await connection.getSigner().signMessage(messageHashBytes); } - public async sendRPC(input: Schema.Input_sendRPC): Promise { + 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); @@ -145,7 +149,7 @@ export class EthereumPlugin extends Plugin { /// Query public async callContractView( - input: Schema.Input_callContractView + input: Query.Input_callContractView ): Promise { const connection = await this.getConnection(input.connection); const contract = connection.getContract( @@ -159,8 +163,8 @@ export class EthereumPlugin extends Plugin { } public async callContractStatic( - input: Schema.Input_callContractStatic - ): Promise { + 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); @@ -190,40 +194,44 @@ export class EthereumPlugin extends Plugin { } } - public encodeParams(input: Schema.Input_encodeParams): string { + public encodeParams(input: Query.Input_encodeParams): string { return defaultAbiCoder.encode(input.types, input.values); } public async getSignerAddress( - input: Schema.Input_getSignerAddress + input: Query.Input_getSignerAddress ): Promise { const connection = await this.getConnection(input.connection); return await connection.getSigner().getAddress(); } public async getSignerBalance( - input: Schema.Input_getSignerBalance + input: Query.Input_getSignerBalance ): Promise { const connection = await this.getConnection(input.connection); - return (await connection.getSigner().getBalance(input.blockTag)).toString(); + return ( + await connection.getSigner().getBalance(input.blockTag || undefined) + ).toString(); } public async getSignerTransactionCount( - input: Schema.Input_getSignerTransactionCount + input: Query.Input_getSignerTransactionCount ): Promise { const connection = await this.getConnection(input.connection); return ( - await connection.getSigner().getTransactionCount(input.blockTag) + await connection + .getSigner() + .getTransactionCount(input.blockTag || undefined) ).toString(); } - public async getGasPrice(input: Schema.Input_getGasPrice): Promise { + 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: Schema.Input_estimateTransactionGas + input: Query.Input_estimateTransactionGas ): Promise { const connection = await this.getConnection(input.connection); return ( @@ -232,15 +240,15 @@ export class EthereumPlugin extends Plugin { } public async estimateContractCallGas( - input: Schema.Input_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 | undefined = input.txOverrides?.gasPrice; - const gasLimit: string | undefined = input.txOverrides?.gasLimit; - const value: string | undefined = input.txOverrides?.value; + 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), @@ -254,7 +262,7 @@ export class EthereumPlugin extends Plugin { return gas.toString(); } - public checkAddress(input: Schema.Input_checkAddress): boolean { + public checkAddress(input: Query.Input_checkAddress): boolean { let address = input.address; try { @@ -274,26 +282,26 @@ export class EthereumPlugin extends Plugin { } } - public toWei(input: Schema.Input_toWei): string { + public toWei(input: Query.Input_toWei): string { const weiAmount = ethers.utils.parseEther(input.eth); return weiAmount.toString(); } - public toEth(input: Schema.Input_toEth): string { + public toEth(input: Query.Input_toEth): string { const etherAmount = ethers.utils.formatEther(input.wei); return etherAmount.toString(); } public async waitForEvent( - input: Schema.Input_waitForEvent - ): Promise { + 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) => { + new Promise((resolve) => { contract.once( filter, (data: string, address: string, log: ethers.providers.Log) => { @@ -301,11 +309,11 @@ export class EthereumPlugin extends Plugin { data, address, log: Mapping.toLog(log), - } as Schema.EventNotification); + } as Types.EventNotification); } ); }), - new Promise((_, reject) => { + new Promise((_, reject) => { setTimeout(function () { reject( `Waiting for event "${input.event}" on contract "${input.address}" timed out` @@ -316,8 +324,8 @@ export class EthereumPlugin extends Plugin { } public async awaitTransaction( - input: Schema.Input_awaitTransaction - ): Promise { + input: Query.Input_awaitTransaction + ): Promise { const connection = await this.getConnection(input.connection); const provider = connection.getProvider(); @@ -333,7 +341,7 @@ export class EthereumPlugin extends Plugin { /// Utils public async getConnection( - connection?: Schema.Connection + connection?: Types.Connection | null ): Promise { if (!connection) { return this._connections[this._defaultNetwork]; @@ -386,7 +394,7 @@ export class EthereumPlugin extends Plugin { return result; } - public parseArgs(args?: string[]): unknown[] { + public parseArgs(args?: string[] | null): unknown[] { if (!args) { return []; } @@ -400,15 +408,15 @@ export class EthereumPlugin extends Plugin { } private async _callContractMethod( - input: Schema.Input_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 | undefined = input.txOverrides?.gasPrice; - const gasLimit: string | undefined = input.txOverrides?.gasLimit; - const value: string | undefined = input.txOverrides?.value; + 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, diff --git a/packages/js/plugins/ethereum/src/manifest.ts b/packages/js/plugins/ethereum/src/manifest.ts deleted file mode 100644 index aab5b15194..0000000000 --- a/packages/js/plugins/ethereum/src/manifest.ts +++ /dev/null @@ -1,249 +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: ` -### Web3API Header START ### -scalar UInt -scalar UInt8 -scalar UInt16 -scalar UInt32 -scalar Int -scalar Int8 -scalar Int16 -scalar Int32 -scalar Bytes -scalar BigInt - -directive @imported( - uri: String! - namespace: String! - nativeType: String! -) on OBJECT | ENUM - -directive @imports( - types: [String!]! -) on OBJECT -### Web3API Header END ### - -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: UInt32! - 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: UInt32 - 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 Query { - callContractView( - address: String! - method: String! - args: [String!] - connection: Connection - ): String! - - callContractStatic( - address: String! - method: String! - args: [String!] - connection: Connection - txOverrides: TxOverrides - ): StaticTxResult! - - encodeParams( - 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! -} - -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 -}`, - implements: [], -}; diff --git a/packages/js/plugins/ethereum/src/mapping.ts b/packages/js/plugins/ethereum/src/mapping.ts index 36b0499f03..37e67d1600 100644 --- a/packages/js/plugins/ethereum/src/mapping.ts +++ b/packages/js/plugins/ethereum/src/mapping.ts @@ -1,4 +1,4 @@ -import { Access, TxReceipt, TxResponse, TxRequest, Log } from "./types"; +import { Access, TxReceipt, TxResponse, TxRequest, Log } from "./w3"; import { ethers } from "ethers"; @@ -31,7 +31,7 @@ export const fromTxReceipt = ( from: receipt.from, contractAddress: receipt.contractAddress, transactionIndex: receipt.transactionIndex, - root: receipt.root, + root: receipt.root || undefined, gasUsed: ethers.BigNumber.from(receipt.gasUsed), logsBloom: receipt.logsBloom, transactionHash: receipt.transactionHash, @@ -41,7 +41,7 @@ export const fromTxReceipt = ( confirmations: receipt.confirmations, cumulativeGasUsed: ethers.BigNumber.from(receipt.cumulativeGasUsed), byzantium: receipt.byzantium, - status: receipt.status, + status: receipt.status || undefined, effectiveGasPrice: ethers.BigNumber.from(receipt.effectiveGasPrice), type: receipt.type, }); @@ -87,15 +87,15 @@ export const toTxRequest = ( export const fromTxRequest = ( request: TxRequest ): ethers.providers.TransactionRequest => ({ - to: request.to, - from: request.from, - nonce: request.nonce, - gasLimit: request.gasLimit, - gasPrice: request.gasPrice, - data: request.data, - value: request.value, - chainId: request.chainId, - type: request.type, + to: request.to || undefined, + from: request.from || undefined, + nonce: request.nonce || undefined, + gasLimit: request.gasLimit || undefined, + gasPrice: request.gasPrice || undefined, + data: request.data || undefined, + value: request.value || undefined, + chainId: request.chainId || undefined, + type: request.type || undefined, }); export const toLog = (log: ethers.providers.Log): Log => ({ diff --git a/packages/js/plugins/ethereum/src/resolvers.ts b/packages/js/plugins/ethereum/src/resolvers.ts index 4a39980155..8e060bcc07 100644 --- a/packages/js/plugins/ethereum/src/resolvers.ts +++ b/packages/js/plugins/ethereum/src/resolvers.ts @@ -1,118 +1,119 @@ import { EthereumPlugin as Plugin } from "."; -import * as Schema from "./types"; +import { Query, Mutation } from "./w3"; +import * as Types from "./w3"; -export const mutation = (plugin: Plugin): Schema.Mutation => ({ +export const mutation = (plugin: Plugin): Mutation.Module => ({ callContractMethod: async ( - input: Schema.Input_callContractMethod - ): Promise => { + input: Mutation.Input_callContractMethod + ): Promise => { return plugin.callContractMethod(input); }, callContractMethodAndWait: async ( - input: Schema.Input_callContractMethodAndWait - ): Promise => { + input: Mutation.Input_callContractMethodAndWait + ): Promise => { return plugin.callContractMethodAndWait(input); }, sendTransaction: async ( - input: Schema.Input_sendTransaction - ): Promise => { + input: Mutation.Input_sendTransaction + ): Promise => { return plugin.sendTransaction(input); }, sendTransactionAndWait: async ( - input: Schema.Input_sendTransactionAndWait - ): Promise => { + input: Mutation.Input_sendTransactionAndWait + ): Promise => { return plugin.sendTransactionAndWait(input); }, deployContract: async ( - input: Schema.Input_deployContract + input: Mutation.Input_deployContract ): Promise => { return plugin.deployContract(input); }, - signMessage: async (input: Schema.Input_signMessage): Promise => { + signMessage: async (input: Mutation.Input_signMessage): Promise => { return plugin.signMessage(input); }, - sendRPC: async (input: Schema.Input_sendRPC): Promise => { + sendRPC: async (input: Mutation.Input_sendRPC): Promise => { return plugin.sendRPC(input); }, }); -export const query = (plugin: Plugin): Schema.Query => ({ +export const query = (plugin: Plugin): Query.Module => ({ callContractView: async ( - input: Schema.Input_callContractView + input: Query.Input_callContractView ): Promise => { return plugin.callContractView(input); }, callContractStatic: async ( - input: Schema.Input_callContractStatic - ): Promise => { + input: Query.Input_callContractStatic + ): Promise => { return plugin.callContractStatic(input); }, - encodeParams: async (input: Schema.Input_encodeParams): Promise => { + encodeParams: async (input: Query.Input_encodeParams): Promise => { return plugin.encodeParams(input); }, getSignerAddress: async ( - input: Schema.Input_getSignerAddress + input: Query.Input_getSignerAddress ): Promise => { return plugin.getSignerAddress(input); }, getSignerBalance: async ( - input: Schema.Input_getSignerBalance + input: Query.Input_getSignerBalance ): Promise => { return plugin.getSignerBalance(input); }, getSignerTransactionCount: async ( - input: Schema.Input_getSignerTransactionCount + input: Query.Input_getSignerTransactionCount ): Promise => { return plugin.getSignerTransactionCount(input); }, - getGasPrice: async (input: Schema.Input_getGasPrice): Promise => { + getGasPrice: async (input: Query.Input_getGasPrice): Promise => { return plugin.getGasPrice(input); }, estimateTransactionGas: async ( - input: Schema.Input_estimateTransactionGas + input: Query.Input_estimateTransactionGas ): Promise => { return plugin.estimateTransactionGas(input); }, estimateContractCallGas: async ( - input: Schema.Input_estimateContractCallGas + input: Query.Input_estimateContractCallGas ): Promise => { return plugin.estimateContractCallGas(input); }, - checkAddress: async (input: Schema.Input_checkAddress): Promise => { + checkAddress: async (input: Query.Input_checkAddress): Promise => { return plugin.checkAddress(input); }, - toWei: async (input: Schema.Input_toWei): Promise => { + toWei: async (input: Query.Input_toWei): Promise => { return plugin.toWei(input); }, - toEth: async (input: Schema.Input_toEth): Promise => { + toEth: async (input: Query.Input_toEth): Promise => { return plugin.toEth(input); }, waitForEvent: async ( - input: Schema.Input_waitForEvent - ): Promise => { + input: Query.Input_waitForEvent + ): Promise => { return plugin.waitForEvent(input); }, awaitTransaction: async ( - input: Schema.Input_awaitTransaction - ): Promise => { + input: Query.Input_awaitTransaction + ): Promise => { return plugin.awaitTransaction(input); }, }); diff --git a/packages/js/plugins/ethereum/src/types.ts b/packages/js/plugins/ethereum/src/types.ts deleted file mode 100644 index fbe2a13eec..0000000000 --- a/packages/js/plugins/ethereum/src/types.ts +++ /dev/null @@ -1,324 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ - -// TODO: generated types here from the schema.graphql to ensure safety `Resolvers` -// https://github.com/web3-api/monorepo/issues/101 -import { PluginModule, Client } 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 String = string; -export type Boolean = boolean; - -/// Objects - -export interface 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; -} - -export interface TxResponse { - hash: string; - to?: string; - from: string; - nonce: UInt32; - gasLimit: BigInt; - gasPrice?: BigInt; - data: string; - value: BigInt; - chainId: UInt32; - blockNumber?: BigInt; - blockHash?: string; - timestamp?: UInt32; - confirmations: UInt32; - raw?: string; - r?: string; - s?: string; - v?: UInt32; - type?: UInt32; - accessList?: Access[]; -} - -export interface TxRequest { - to?: string; - from?: string; - nonce?: UInt32; - gasLimit?: BigInt; - gasPrice?: BigInt; - data?: string; - value?: BigInt; - chainId?: UInt32; - type?: UInt32; -} - -export interface TxOverrides { - gasLimit?: BigInt; - gasPrice?: BigInt; - value?: BigInt; -} - -export interface StaticTxResult { - result: string; - error: boolean; -} - -export interface Log { - blockNumber: BigInt; - blockHash: string; - transactionIndex: UInt32; - removed: boolean; - address: string; - data: string; - topics: string[]; - transactionHash: string; - logIndex: UInt32; -} - -export interface EventNotification { - data: string; - address: string; - log: Log; -} - -export interface Access { - address: string; - storageKeys: string[]; -} - -export interface Connection { - node?: string; - networkNameOrChainId?: string; -} - -/// Queries - -export interface Input_callContractView extends Record { - address: string; - method: string; - args?: string[]; - connection?: Connection; -} - -export interface Input_callContractStatic extends Record { - address: string; - method: string; - args?: string[]; - connection?: Connection; - txOverrides?: TxOverrides; -} - -export interface Input_encodeParams extends Record { - types: string[]; - values: string[]; -} - -export interface Input_getSignerAddress extends Record { - connection?: Connection; -} - -export interface Input_getSignerBalance extends Record { - blockTag?: BigInt; - connection?: Connection; -} - -export interface Input_getSignerTransactionCount - extends Record { - blockTag?: BigInt; - connection?: Connection; -} - -export interface Input_getGasPrice extends Record { - connection?: Connection; -} - -export interface Input_estimateTransactionGas extends Record { - tx: TxRequest; - connection?: Connection; -} - -export interface Input_estimateContractCallGas extends Record { - address: string; - method: string; - args?: string[]; - connection?: Connection; - txOverrides?: TxOverrides; -} - -export interface Input_checkAddress extends Record { - address: string; -} - -export interface Input_toWei extends Record { - eth: string; -} - -export interface Input_toEth extends Record { - wei: BigInt; -} - -export interface Input_awaitTransaction extends Record { - txHash: string; - confirmations: UInt32; - timeout: UInt32; - connection?: Connection; -} - -export interface Input_waitForEvent extends Record { - address: string; - event: string; - args?: string[]; - timeout?: UInt32; - connection?: Connection; -} - -export interface Query extends PluginModule { - callContractView( - input: Input_callContractView, - client: Client - ): Promise; - - callContractStatic( - input: Input_callContractStatic, - client: Client - ): Promise; - - encodeParams(input: Input_encodeParams, client: Client): Promise; - - getSignerAddress( - input: Input_getSignerAddress, - client: Client - ): Promise; - - getSignerBalance( - input: Input_getSignerBalance, - client: Client - ): Promise; - - getSignerTransactionCount( - input: Input_getSignerTransactionCount, - client: Client - ): Promise; - - getGasPrice(input: Input_getGasPrice, client: Client): Promise; - - estimateTransactionGas( - input: Input_estimateTransactionGas, - client: Client - ): Promise; - - estimateContractCallGas( - input: Input_estimateContractCallGas, - client: Client - ): Promise; - - checkAddress(input: Input_checkAddress, client: Client): Promise; - - toWei(input: Input_toWei, client: Client): Promise; - - toEth(input: Input_toEth, client: Client): Promise; - - awaitTransaction( - input: Input_awaitTransaction, - client: Client - ): Promise; - - waitForEvent( - input: Input_waitForEvent, - client: Client - ): Promise; -} - -export interface Input_callContractMethod extends Record { - address: string; - method: string; - args?: string[]; - connection?: Connection; - txOverrides?: TxOverrides; -} - -export interface Input_callContractMethodAndWait - extends Record { - address: string; - method: string; - args?: string[]; - connection?: Connection; - txOverrides?: TxOverrides; -} - -export interface Input_sendTransaction extends Record { - tx: TxRequest; - connection?: Connection; -} - -export interface Input_sendTransactionAndWait extends Record { - tx: TxRequest; - connection?: Connection; -} - -export interface Input_deployContract extends Record { - abi: string; - bytecode: string; - args?: string[]; - connection?: Connection; -} - -export interface Input_signMessage extends Record { - message: string; - connection?: Connection; -} - -export interface Input_sendRPC extends Record { - method: string; - params: string[]; - connection?: Connection; -} - -export interface Mutation extends PluginModule { - callContractMethod( - input: Input_callContractMethod, - client: Client - ): Promise; - - callContractMethodAndWait( - input: Input_callContractMethodAndWait, - client: Client - ): Promise; - - sendTransaction( - input: Input_sendTransaction, - client: Client - ): Promise; - - sendTransactionAndWait( - input: Input_sendTransactionAndWait, - client: Client - ): Promise; - - deployContract(input: Input_deployContract, client: Client): Promise; - - signMessage(input: Input_signMessage, client: Client): Promise; - - sendRPC(input: Input_sendRPC, client: Client): Promise; -} diff --git a/packages/js/plugins/graph-node/package.json b/packages/js/plugins/graph-node/package.json index 21257ee74d..de3510696f 100644 --- a/packages/js/plugins/graph-node/package.json +++ b/packages/js/plugins/graph-node/package.json @@ -13,7 +13,8 @@ "schema.graphql" ], "scripts": { - "build": "rimraf ./build && tsc --project tsconfig.build.json", + "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "codegen": "npx -p @web3api/cli w3 plugin codegen", "lint": "eslint --color --ext .ts src/", "test": "jest --passWithNoTests --runInBand --verbose", "test:ci": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/graph-node/schema.graphql b/packages/js/plugins/graph-node/schema.graphql index 84cfcc4659..dbfa7a3553 100644 --- a/packages/js/plugins/graph-node/schema.graphql +++ b/packages/js/plugins/graph-node/schema.graphql @@ -1,3 +1,5 @@ +#import { Query } into HTTP from "ens/http.web3api.eth" + type Query { querySubgraph( subgraphAuthor: String! diff --git a/packages/js/plugins/graph-node/src/index.ts b/packages/js/plugins/graph-node/src/index.ts index da1177fd42..46a3d66242 100644 --- a/packages/js/plugins/graph-node/src/index.ts +++ b/packages/js/plugins/graph-node/src/index.ts @@ -1,5 +1,5 @@ import { query } from "./resolvers"; -import { manifest } from "./manifest"; +import { manifest, Query, HTTP_Query } from "./w3"; import { RequestData, RequestError } from "./types"; import { @@ -7,7 +7,6 @@ import { Plugin, PluginFactory, PluginPackageManifest, - PluginModules, } from "@web3api/core-js"; export interface GraphNodeConfig { @@ -23,9 +22,11 @@ export class GraphNodePlugin extends Plugin { return manifest; } - // TODO: generated types here from the schema.graphql to ensure safety `Resolvers` - // https://github.com/web3-api/monorepo/issues/101 - public getModules(client: Client): PluginModules { + public getModules( + client: Client + ): { + query: Query.Module; + } { return { query: query(this, client), }; @@ -37,22 +38,8 @@ export class GraphNodePlugin extends Plugin { query: string, client: Client ): Promise { - const { data, errors } = await client.query<{ - post: { - status: number; - statusText: string; - headers: { key: string; value: string }[]; - body: string; - }; - }>({ - uri: "ens/http.web3api.eth", - query: `query { - post( - url: $url, - request: $request - ) - }`, - variables: { + const { data, error } = await HTTP_Query.post( + { url: `${this._config.provider}/subgraphs/name/${author}/${name}`, request: { body: JSON.stringify({ @@ -61,21 +48,22 @@ export class GraphNodePlugin extends Plugin { responseType: "TEXT", }, }, - }); + client + ); - if (errors) { - throw new Error(`GraphNodePlugin: errors encountered. Errors: - ${errors.map((err: Error) => JSON.stringify(err)).join("\n")} - `); + if (error) { + throw new Error(`GraphNodePlugin: errors encountered. Error: ${error}`); } - if (!data || !data.post) { + if (!data) { throw new Error(`GraphNodePlugin: data is undefined.`); } - const responseJson = (data.post.body as unknown) as - | RequestError - | RequestData; + if (!data.body) { + throw Error(`GraphNodePlugin: body is undefined.`); + } + + const responseJson = JSON.parse(data.body) as RequestError | RequestData; const responseErrors = (responseJson as RequestError).errors; diff --git a/packages/js/plugins/graph-node/src/resolvers.ts b/packages/js/plugins/graph-node/src/resolvers.ts index a98a5755b1..dfe9527b1d 100644 --- a/packages/js/plugins/graph-node/src/resolvers.ts +++ b/packages/js/plugins/graph-node/src/resolvers.ts @@ -1,16 +1,13 @@ import { GraphNodePlugin } from "."; +import { Query } from "./w3"; -import { Client, PluginModule } from "@web3api/core-js"; +import { Client } from "@web3api/core-js"; export const query = ( graphnode: GraphNodePlugin, client: Client -): PluginModule => ({ - querySubgraph: async (input: { - subgraphAuthor: string; - subgraphName: string; - query: string; - }): Promise => { +): Query.Module => ({ + querySubgraph: async (input: Query.Input_querySubgraph): Promise => { return await graphnode.query( input.subgraphAuthor, input.subgraphName, diff --git a/packages/js/plugins/graph-node/web3api.plugin.yaml b/packages/js/plugins/graph-node/web3api.plugin.yaml new file mode 100644 index 0000000000..b21359a846 --- /dev/null +++ b/packages/js/plugins/graph-node/web3api.plugin.yaml @@ -0,0 +1,3 @@ +format: 0.0.1-prealpha.1 +language: plugin/typescript +schema: ./schema.graphql diff --git a/packages/js/plugins/http/package.json b/packages/js/plugins/http/package.json index e28b3b4e18..4aa2b111fc 100644 --- a/packages/js/plugins/http/package.json +++ b/packages/js/plugins/http/package.json @@ -13,7 +13,8 @@ "schema.graphql" ], "scripts": { - "build": "rimraf ./build && tsc --project tsconfig.build.json", + "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "codegen": "npx -p @web3api/cli w3 plugin codegen", "lint": "eslint --color --ext .ts src/", "lint:fix": "eslint --color --fix --ext .ts src/", "test": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/http/schema.graphql b/packages/js/plugins/http/schema.graphql index 4d6cf9ff78..56eac34601 100644 --- a/packages/js/plugins/http/schema.graphql +++ b/packages/js/plugins/http/schema.graphql @@ -18,16 +18,14 @@ type Response { type Request { headers: [Header!] urlParams: [UrlParam!] - responseType: String! # "TEXT" || "BINARY" + responseType: ResponseType! body: String } -# Enum types curently not supported -# -# enum ResponseType { -# TEXT -# BINARY -# } +enum ResponseType { + TEXT + BINARY +} type Query { get(url: String!, request: Request): Response 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 545e1a9666..c708458f77 100644 --- a/packages/js/plugins/http/src/__tests__/e2e/e2e.spec.ts +++ b/packages/js/plugins/http/src/__tests__/e2e/e2e.spec.ts @@ -1,6 +1,6 @@ import { Web3ApiClient } from "@web3api/client-js" import { httpPlugin } from "../.."; -import { Response } from "../../types"; +import { Response } from "../../w3"; import nock from "nock" const defaultReplyHeaders = { @@ -49,7 +49,7 @@ describe("e2e tests for HttpPlugin", () => { expect(response.data?.get.status).toBe(200) // expect(response.data?.get.statusText).toBe("OK") expect(response.data?.get.body).toBe('{data: "test-response"}') - expect(response.data?.get.headers.length).toEqual(2) // default reply headers + expect(response.data?.get.headers?.length).toEqual(2) // default reply headers }); test("succesfull request with response type as BINARY", async () => { @@ -77,7 +77,7 @@ describe("e2e tests for HttpPlugin", () => { expect(response.data?.get.status).toBe(200) // expect(response.data?.get.statusText).toBe("OK") expect(response.data?.get.body).toBe(Buffer.from('{data: "test-response"}').toString('base64')) - expect(response.data?.get.headers.length).toEqual(2) // default reply headers + expect(response.data?.get.headers?.length).toEqual(2) // default reply headers }); test("succesfull request with query params and request headers", async () => { @@ -169,7 +169,7 @@ describe("e2e tests for HttpPlugin", () => { expect(response.data?.post.status).toBe(200) // expect(response.data?.get.statusText).toBe("OK") expect(response.data?.post.body).toBe('{data: "test-response"}') - expect(response.data?.post.headers.length).toEqual(2) // default reply headers + expect(response.data?.post.headers?.length).toEqual(2) // default reply headers }); test("succesfull request with response type as BINARY", async () => { @@ -198,7 +198,7 @@ describe("e2e tests for HttpPlugin", () => { expect(response.data?.post.status).toBe(200) // expect(response.data?.get.statusText).toBe("OK") expect(response.data?.post.body).toBe(Buffer.from('{data: "test-response"}').toString('base64')) - expect(response.data?.post.headers.length).toEqual(2) // default reply headers + expect(response.data?.post.headers?.length).toEqual(2) // default reply headers }); test("succesfull request with query params and request headers", async () => { 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 f58140df85..7396a23954 100644 --- a/packages/js/plugins/http/src/__tests__/unit/index.test.ts +++ b/packages/js/plugins/http/src/__tests__/unit/index.test.ts @@ -1,4 +1,5 @@ -import { HttpPlugin } from "../../index"; +import { HttpPlugin, } from "../../index"; +import { ResponseTypeEnum } from "../../w3"; import axios, { AxiosResponse, AxiosRequestConfig } from "axios"; @@ -35,7 +36,7 @@ describe("test http plugin", () => { { key: "X-Test-Header", value: "test-header-value" }, ], urlParams: [{ key: "q", value: "test-param" }], - responseType: "TEXT", + responseType: ResponseTypeEnum.TEXT, }); expect(mockedAxios.get).lastCalledWith("/api/test", { @@ -89,7 +90,10 @@ describe("test http plugin", () => { expect(response.headers).toStrictEqual([ { key: "Content-Type", value: "application/json; charset=utf-8" }, ]); - expect(Buffer.from(response.body, 'base64').toString()).toBe("{result: 1001}"); + expect(response.body).toBeTruthy(); + if (response.body) { + expect(Buffer.from(response.body, 'base64').toString()).toBe("{result: 1001}"); + } }); }); @@ -169,7 +173,10 @@ describe("test http plugin", () => { expect(response.headers).toStrictEqual([ { key: "Content-Type", value: "application/json; charset=utf-8" }, ]); - expect(Buffer.from(response.body, 'base64').toString()).toBe("{response: 1001}"); + 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 479274ce0c..f14bbf38e7 100644 --- a/packages/js/plugins/http/src/__tests__/unit/util.test.ts +++ b/packages/js/plugins/http/src/__tests__/unit/util.test.ts @@ -1,4 +1,5 @@ import { fromAxiosResponse, toAxiosRequestConfig } from "../../util"; +import { ResponseTypeEnum } from "../../w3"; describe("converting axios response", () => { test("response type: text", () => { @@ -60,7 +61,7 @@ describe("creating axios config", () => { test("with url params", () => { const config = toAxiosRequestConfig({ urlParams: [{ key: "tag", value: "data" }], - responseType: "BINARY", + responseType: ResponseTypeEnum.BINARY, body: "body-content", }); diff --git a/packages/js/plugins/http/src/index.ts b/packages/js/plugins/http/src/index.ts index ce38a30415..7f2dd605f7 100644 --- a/packages/js/plugins/http/src/index.ts +++ b/packages/js/plugins/http/src/index.ts @@ -1,14 +1,12 @@ /* eslint-disable import/no-extraneous-dependencies */ import { query } from "./resolvers"; -import { Request, Response } from "./types"; import { fromAxiosResponse, toAxiosRequestConfig } from "./util"; -import { manifest } from "./manifest"; +import { manifest, Response, Request, Query } from "./w3"; import axios from "axios"; import { Client, Plugin, - PluginModules, PluginPackageManifest, PluginPackage, } from "@web3api/core-js"; @@ -22,25 +20,29 @@ export class HttpPlugin extends Plugin { return manifest; } - public getModules(_client: Client): PluginModules { + public getModules( + _client: Client + ): { + query: Query.Module; + } { return { query: query(this), }; } - public async get(url: string, request: Request): Promise { + public async get(url: string, request?: Request): Promise { const response = await axios.get( url, - toAxiosRequestConfig(request) + request ? toAxiosRequestConfig(request) : undefined ); return fromAxiosResponse(response); } - public async post(url: string, request: Request): Promise { + public async post(url: string, request?: Request): Promise { const response = await axios.post( url, - request.body, - toAxiosRequestConfig(request) + request ? request.body : undefined, + request ? toAxiosRequestConfig(request) : undefined ); return fromAxiosResponse(response); } diff --git a/packages/js/plugins/http/src/manifest.ts b/packages/js/plugins/http/src/manifest.ts deleted file mode 100644 index d06d1e48eb..0000000000 --- a/packages/js/plugins/http/src/manifest.ts +++ /dev/null @@ -1,44 +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 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: String! # "TEXT" || "BINARY" - body: String -} - -# Enum types curently not supported -# -# enum ResponseType { -# TEXT -# BINARY -# } - -type Query { - get(url: String!, request: Request): Response - post(url: String!, request: Request): Response -} -`, - implements: [], -}; diff --git a/packages/js/plugins/http/src/resolvers.ts b/packages/js/plugins/http/src/resolvers.ts index 67a073cf55..924b667ec2 100644 --- a/packages/js/plugins/http/src/resolvers.ts +++ b/packages/js/plugins/http/src/resolvers.ts @@ -1,13 +1,11 @@ import { HttpPlugin } from "."; -import { Request } from "./types"; +import { Query } from "./w3"; -import { PluginModule } from "@web3api/core-js"; - -export const query = (http: HttpPlugin): PluginModule => ({ - get: async (input: { url: string; request: Request }) => { - return await http.get(input.url, input.request); +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: { url: string; request: Request }) => { - return await http.post(input.url, input.request); + post: async (input: Query.Input_post) => { + return await http.post(input.url, input.request || undefined); }, }); diff --git a/packages/js/plugins/http/src/types.ts b/packages/js/plugins/http/src/types.ts deleted file mode 100644 index 49668a7307..0000000000 --- a/packages/js/plugins/http/src/types.ts +++ /dev/null @@ -1,28 +0,0 @@ -// TODO: Generate this from the schema.graphql file -// https://github.com/web3-api/monorepo/issues/101 - -export class Header { - key: string; - value: string; -} - -export class UrlParam { - key: string; - value: string; -} - -export type ResponseType = "TEXT" | "BINARY"; - -export class Request { - headers?: Header[]; - urlParams?: UrlParam[]; - responseType: ResponseType; - body?: string; -} - -export class Response { - status: number; - statusText: string; - headers: Header[]; - body: string; -} diff --git a/packages/js/plugins/http/src/util.ts b/packages/js/plugins/http/src/util.ts index 1f9c9b553e..f21e130e37 100644 --- a/packages/js/plugins/http/src/util.ts +++ b/packages/js/plugins/http/src/util.ts @@ -1,4 +1,4 @@ -import { Request, Response, Header } from "./types"; +import { Request, Response, ResponseTypeEnum, Header } from "./w3"; import { AxiosResponse, AxiosRequestConfig } from "axios"; @@ -8,7 +8,7 @@ import { AxiosResponse, AxiosRequestConfig } from "axios"; * @param axiosResponse */ export function fromAxiosResponse( - axiosResponse: AxiosResponse + axiosResponse: AxiosResponse ): Response { const responseHeaders: Header[] = []; for (const key of Object.keys(axiosResponse.headers)) { @@ -23,15 +23,31 @@ export function fromAxiosResponse( // encode bytes as base64 string if response is array buffer if (axiosResponse.config.responseType == "arraybuffer") { + if (!Buffer.isBuffer(axiosResponse.data)) { + throw Error( + "HttpPlugin: Axios response data malformed, must be a buffer. Type: " + + typeof axiosResponse.data + ); + } + return { ...response, body: Buffer.from(axiosResponse.data).toString("base64"), }; } else { - return { - ...response, - body: axiosResponse.data, - }; + switch (typeof axiosResponse.data) { + case "string": + case "undefined": + return { + ...response, + body: axiosResponse.data, + }; + default: + return { + ...response, + body: JSON.stringify(axiosResponse.data), + }; + } } } @@ -49,8 +65,16 @@ export function toAxiosRequestConfig(request: Request): AxiosRequestConfig { return { ...headers, [h.key]: h.value }; }, {}); + let responseType: "text" | "arraybuffer" = "text"; + + switch (request.responseType) { + case "BINARY": + case ResponseTypeEnum.BINARY: + responseType = "arraybuffer"; + } + let config: AxiosRequestConfig = { - responseType: request.responseType == "BINARY" ? "arraybuffer" : "text", + responseType, }; if (urlParams) { diff --git a/packages/js/plugins/http/web3api.plugin.yaml b/packages/js/plugins/http/web3api.plugin.yaml new file mode 100644 index 0000000000..b21359a846 --- /dev/null +++ b/packages/js/plugins/http/web3api.plugin.yaml @@ -0,0 +1,3 @@ +format: 0.0.1-prealpha.1 +language: plugin/typescript +schema: ./schema.graphql diff --git a/packages/js/plugins/ipfs/jest.config.js b/packages/js/plugins/ipfs/jest.config.js new file mode 100644 index 0000000000..38888109ca --- /dev/null +++ b/packages/js/plugins/ipfs/jest.config.js @@ -0,0 +1,13 @@ +module.exports = { + "roots": [ + "/src" + ], + "testMatch": [ + "**/__tests__/**/*.+(ts|tsx|js)", + "**/?(*.)+(spec|test).+(ts|tsx|js)" + ], + "transform": { + "^.+\\.(ts|tsx)$": "ts-jest" + }, + testEnvironment: 'node' +} diff --git a/packages/js/plugins/ipfs/package.json b/packages/js/plugins/ipfs/package.json index de687c907a..e8f79ac9b4 100644 --- a/packages/js/plugins/ipfs/package.json +++ b/packages/js/plugins/ipfs/package.json @@ -13,7 +13,8 @@ "schema.graphql" ], "scripts": { - "build": "rimraf build && tsc --project tsconfig.build.json", + "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "codegen": "npx -p @web3api/cli w3 plugin codegen", "lint": "eslint --color --ext .ts src/", "test": "jest --passWithNoTests --runInBand --verbose", "test:ci": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/ipfs/schema.graphql b/packages/js/plugins/ipfs/schema.graphql index a938d01ad1..6704c0f786 100644 --- a/packages/js/plugins/ipfs/schema.graphql +++ b/packages/js/plugins/ipfs/schema.graphql @@ -1,32 +1,6 @@ -### Web3API Header START ### -scalar UInt -scalar UInt8 -scalar UInt16 -scalar UInt32 -scalar Int -scalar Int8 -scalar Int16 -scalar Int32 -scalar Bytes -scalar BigInt +#import { Query, MaybeUriOrManifest } into UriResolver from "ens/uri-resolver.core.web3api.eth" -directive @imported( - uri: String! - namespace: String! - nativeType: String! -) on OBJECT | ENUM - -directive @imports( - types: [String!]! -) on OBJECT -### Web3API Header END ### - -type Query implements UriResolver_Query @imports( - types: [ - "UriResolver_Query", - "UriResolver_MaybeUriOrManifest" - ] -) { +type Query implements UriResolver_Query { catFile( cid: String! options: Options @@ -66,35 +40,3 @@ type Options { # The IPFS provider to be used provider: String } - -### Imported Queries START ### - -type UriResolver_Query @imported( - uri: "w3://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: "w3://ens/uri-resolver.core.web3api.eth", - namespace: "UriResolver", - nativeType: "MaybeUriOrManifest" -) { - uri: String - manifest: String -} - -### Imported Objects END ### diff --git a/packages/js/plugins/ipfs/src/index.ts b/packages/js/plugins/ipfs/src/index.ts index fb3b8862d8..da73e467d5 100644 --- a/packages/js/plugins/ipfs/src/index.ts +++ b/packages/js/plugins/ipfs/src/index.ts @@ -1,13 +1,11 @@ import { query, mutation } from "./resolvers"; -import { manifest } from "./manifest"; -import { Options, ResolveResult } from "./types"; +import { manifest, Query, Mutation, Options, ResolveResult } from "./w3"; import { Client, Plugin, PluginFactory, PluginPackageManifest, - PluginModules, } from "@web3api/core-js"; import CID from "cids"; import AbortController from "abort-controller"; @@ -61,9 +59,12 @@ export class IpfsPlugin extends Plugin { return isIPFS.cid(cid) || isIPFS.cidPath(cid) || isIPFS.ipfsPath(cid); } - // TODO: generated types here from the schema.graphql to ensure safety `Resolvers` - // https://github.com/web3-api/monorepo/issues/101 - public getModules(_client: Client): PluginModules { + public getModules( + _client: Client + ): { + query: Query.Module; + mutation: Mutation.Module; + } { return { query: query(this), mutation: mutation(this), diff --git a/packages/js/plugins/ipfs/src/manifest.ts b/packages/js/plugins/ipfs/src/manifest.ts deleted file mode 100644 index 317523fbfa..0000000000 --- a/packages/js/plugins/ipfs/src/manifest.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { PluginPackageManifest, coreInterfaceUris } from "@web3api/core-js"; - -export const manifest: PluginPackageManifest = { - // TODO: use the schema.graphql - // https://github.com/web3-api/monorepo/issues/101 - schema: `### Web3API Header START ### -scalar UInt -scalar UInt8 -scalar UInt16 -scalar UInt32 -scalar Int -scalar Int8 -scalar Int16 -scalar Int32 -scalar Bytes -scalar BigInt - -directive @imported( - uri: String! - namespace: String! - nativeType: String! -) on OBJECT | ENUM - -directive @imports( - types: [String!]! -) on OBJECT -### 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 { - # TODO: Allow for custom type CID - # https://github.com/web3-api/monorepo/issues/103 - addFile(data: Bytes!): String! -} - -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 -} - -### Imported Queries START ### - -type UriResolver_Query @imported( - uri: "w3://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: "w3://ens/uri-resolver.core.web3api.eth", - namespace: "UriResolver", - nativeType: "MaybeUriOrManifest" -) { - uri: String - manifest: String -} - -### Imported Objects END ###`, - implements: [coreInterfaceUris.uriResolver], -}; diff --git a/packages/js/plugins/ipfs/src/resolvers.ts b/packages/js/plugins/ipfs/src/resolvers.ts index f71f937489..da146455a1 100644 --- a/packages/js/plugins/ipfs/src/resolvers.ts +++ b/packages/js/plugins/ipfs/src/resolvers.ts @@ -1,29 +1,22 @@ import { IpfsPlugin } from "./"; -import { ResolveResult, Options } from "./types"; +import { ResolveResult, Query, Mutation } from "./w3"; -import { PluginModule } from "@web3api/core-js"; - -// TODO: generate types from the schema -// https://github.com/web3-api/monorepo/issues/101 -export const mutation = (ipfs: IpfsPlugin): PluginModule => ({ - addFile: async (input: { data: Uint8Array }) => { +export const mutation = (ipfs: IpfsPlugin): Mutation.Module => ({ + addFile: async (input: Mutation.Input_addFile) => { const { hash } = await ipfs.add(input.data); - return hash; + return hash.toString(); }, }); -export const query = (ipfs: IpfsPlugin): PluginModule => ({ - catFile: async (input: { cid: string; options?: Options }) => { - return await ipfs.cat(input.cid, input.options); +export const query = (ipfs: IpfsPlugin): Query.Module => ({ + catFile: async (input: Query.Input_catFile) => { + return await ipfs.cat(input.cid, input.options || undefined); }, - resolve: async (input: { - cid: string; - options?: Options; - }): Promise => { - return await ipfs.resolve(input.cid, input.options); + resolve: async (input: Query.Input_resolve): Promise => { + return await ipfs.resolve(input.cid, input.options || undefined); }, // uri-resolver.core.web3api.eth - tryResolveUri: async (input: { authority: string; path: string }) => { + tryResolveUri: async (input: Query.Input_tryResolveUri) => { if (input.authority !== "ipfs") { return null; } @@ -59,7 +52,7 @@ export const query = (ipfs: IpfsPlugin): PluginModule => ({ // Nothing found return { manifest: null, uri: null }; }, - getFile: async (input: { path: string }) => { + getFile: async (input: Query.Input_getFile) => { try { const { cid, provider } = await ipfs.resolve(input.path, { timeout: 5000, diff --git a/packages/js/plugins/ipfs/src/types.ts b/packages/js/plugins/ipfs/src/types.ts deleted file mode 100644 index 4da6180a65..0000000000 --- a/packages/js/plugins/ipfs/src/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -// TODO: generate types from the schema -// https://github.com/web3-api/monorepo/issues/101 - -export interface ResolveResult { - cid: string; - provider: string; -} - -export interface Options { - timeout?: number; - provider?: string; -} diff --git a/packages/js/plugins/ipfs/web3api.plugin.yaml b/packages/js/plugins/ipfs/web3api.plugin.yaml new file mode 100644 index 0000000000..b21359a846 --- /dev/null +++ b/packages/js/plugins/ipfs/web3api.plugin.yaml @@ -0,0 +1,3 @@ +format: 0.0.1-prealpha.1 +language: plugin/typescript +schema: ./schema.graphql diff --git a/packages/js/plugins/logger/package.json b/packages/js/plugins/logger/package.json index 44e3c1b047..0eb38a4aed 100644 --- a/packages/js/plugins/logger/package.json +++ b/packages/js/plugins/logger/package.json @@ -13,7 +13,8 @@ "version": "0.0.1-prealpha.35", "main": "build/index.js", "scripts": { - "build": "rimraf ./build && tsc --project tsconfig.build.json", + "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "codegen": "npx -p @web3api/cli w3 plugin codegen", "lint": "eslint --color --ext .ts src/", "test": "jest --passWithNoTests --runInBand --verbose", "test:ci": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/logger/schema.graphql b/packages/js/plugins/logger/schema.graphql index 9e979276eb..59136b705e 100644 --- a/packages/js/plugins/logger/schema.graphql +++ b/packages/js/plugins/logger/schema.graphql @@ -1,64 +1,8 @@ -### Web3API Header START ### -scalar UInt -scalar UInt8 -scalar UInt16 -scalar UInt32 -scalar Int -scalar Int8 -scalar Int16 -scalar Int32 -scalar Bytes -scalar BigInt +#import { Query, LogLevel } into Logger from "ens/logger.core.web3api.eth" -directive @imported( - uri: String! - namespace: String! - nativeType: String! -) on OBJECT | ENUM - -directive @imports( - types: [String!]! -) on OBJECT -### 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: "w3://ens/logger.core.web3api.eth", - namespace: "Logger", - nativeType: "Query" -) { +type Query implements Logger_Query { log( level: Logger_LogLevel! message: String! ): Boolean! } - -### Imported Queries END ### - -### Imported Objects START ### - -enum Logger_LogLevel @imported( - uri: "w3://ens/logger.core.web3api.eth", - namespace: "Logger", - nativeType: "LogLevel" -) { - DEBUG - INFO - WARN - ERROR -} - -### Imported Objects END ### diff --git a/packages/js/plugins/logger/src/__tests__/e2e/e2e.spec.ts b/packages/js/plugins/logger/src/__tests__/e2e/e2e.spec.ts index d35c2be0f1..f0edcdeae7 100644 --- a/packages/js/plugins/logger/src/__tests__/e2e/e2e.spec.ts +++ b/packages/js/plugins/logger/src/__tests__/e2e/e2e.spec.ts @@ -1,5 +1,4 @@ -import { Web3ApiClient } from "@web3api/client-js" -import { LogLevel } from "../.."; +import { Web3ApiClient } from "@web3api/client-js"; describe("log method", () => { @@ -11,7 +10,7 @@ describe("log method", () => { query: ` query { log( - level: ${LogLevel.DEBUG} + level: DEBUG message: "Test message" ) } diff --git a/packages/js/plugins/logger/src/index.ts b/packages/js/plugins/logger/src/index.ts index 0d31bfcce6..f16d52afb9 100644 --- a/packages/js/plugins/logger/src/index.ts +++ b/packages/js/plugins/logger/src/index.ts @@ -1,21 +1,9 @@ import { query } from "./resolvers"; -import { manifest } from "./manifest"; +import { manifest, Query, Logger_LogLevel, Logger_LogLevelEnum } from "./w3"; -import { - Plugin, - PluginPackageManifest, - PluginModules, - PluginPackage, -} from "@web3api/core-js"; +import { Plugin, PluginPackageManifest, PluginPackage } from "@web3api/core-js"; -export enum LogLevel { - DEBUG, - INFO, - WARN, - ERROR, -} - -export type LogFunc = (level: LogLevel, message: string) => boolean; +export type LogFunc = (level: Logger_LogLevel, message: string) => boolean; export class LoggerPlugin extends Plugin { private _logFunc?: LogFunc; @@ -29,28 +17,34 @@ export class LoggerPlugin extends Plugin { return manifest; } - public getModules(): PluginModules { + public getModules(): { + query: Query.Module; + } { return { query: query(this), }; } - public log(level: LogLevel, message: string): boolean { + public log(level: Logger_LogLevel, message: string): boolean { if (this._logFunc) { return this._logFunc(level, message); } switch (level) { - case LogLevel.DEBUG: + case "DEBUG": + case Logger_LogLevelEnum.DEBUG: console.debug(message); break; - case LogLevel.WARN: + case "WARN": + case Logger_LogLevelEnum.WARN: console.warn(message); break; - case LogLevel.ERROR: + case "ERROR": + case Logger_LogLevelEnum.ERROR: console.error(message); break; - case LogLevel.INFO: + case "INFO": + case Logger_LogLevelEnum.INFO: console.log(message); break; default: diff --git a/packages/js/plugins/logger/src/manifest.ts b/packages/js/plugins/logger/src/manifest.ts deleted file mode 100644 index 36588603b5..0000000000 --- a/packages/js/plugins/logger/src/manifest.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { PluginPackageManifest, coreInterfaceUris } from "@web3api/core-js"; - -export const manifest: PluginPackageManifest = { - // TODO: use the schema.graphql - // https://github.com/web3-api/monorepo/issues/101 - schema: `### Web3API Header START ### -scalar UInt -scalar UInt8 -scalar UInt16 -scalar UInt32 -scalar Int -scalar Int8 -scalar Int16 -scalar Int32 -scalar Bytes -scalar BigInt - -directive @imported( - uri: String! - namespace: String! - nativeType: String! -) on OBJECT | ENUM - -directive @imports( - types: [String!]! -) on OBJECT -### 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: "w3://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: "w3://ens/logger.core.web3api.eth", - namespace: "Logger", - nativeType: "LogLevel" -) { - DEBUG - INFO - WARN - ERROR -} - -### Imported Objects END ### -`, - implements: [coreInterfaceUris.logger], -}; diff --git a/packages/js/plugins/logger/src/resolvers.ts b/packages/js/plugins/logger/src/resolvers.ts index 6aa965e6ce..d1b2aaa1f4 100644 --- a/packages/js/plugins/logger/src/resolvers.ts +++ b/packages/js/plugins/logger/src/resolvers.ts @@ -1,9 +1,8 @@ -import { LoggerPlugin, LogLevel } from "."; +import { LoggerPlugin } from "."; +import { Query } from "./w3"; -import { PluginModule } from "@web3api/core-js"; - -export const query = (plugin: LoggerPlugin): PluginModule => ({ - log: (input: { level: LogLevel; message: string }) => { +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/web3api.plugin.yaml b/packages/js/plugins/logger/web3api.plugin.yaml new file mode 100644 index 0000000000..b21359a846 --- /dev/null +++ b/packages/js/plugins/logger/web3api.plugin.yaml @@ -0,0 +1,3 @@ +format: 0.0.1-prealpha.1 +language: plugin/typescript +schema: ./schema.graphql diff --git a/packages/js/plugins/sha3/package.json b/packages/js/plugins/sha3/package.json index 7304665a65..5907485196 100644 --- a/packages/js/plugins/sha3/package.json +++ b/packages/js/plugins/sha3/package.json @@ -13,7 +13,8 @@ "schema.graphql" ], "scripts": { - "build": "rimraf build && tsc --project tsconfig.build.json", + "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "codegen": "npx -p @web3api/cli w3 plugin codegen", "lint": "eslint --color --ext .ts src/", "test": "jest --passWithNoTests --runInBand --verbose", "test:ci": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/sha3/src/index.ts b/packages/js/plugins/sha3/src/index.ts index 5e1af4ee9b..0c77a29a48 100644 --- a/packages/js/plugins/sha3/src/index.ts +++ b/packages/js/plugins/sha3/src/index.ts @@ -1,19 +1,16 @@ -import { manifest } from "./manifest"; +import { manifest, Query } from "./w3"; import { query } from "./resolvers"; -import { - Plugin, - PluginPackageManifest, - PluginModules, - PluginPackage, -} from "@web3api/core-js"; +import { Plugin, PluginPackageManifest, PluginPackage } from "@web3api/core-js"; export class SHA3Plugin extends Plugin { public static manifest(): PluginPackageManifest { return manifest; } - getModules(): PluginModules { + getModules(): { + query: Query.Module; + } { return { query: query(), }; diff --git a/packages/js/plugins/sha3/src/manifest.ts b/packages/js/plugins/sha3/src/manifest.ts deleted file mode 100644 index 15c70eb4de..0000000000 --- a/packages/js/plugins/sha3/src/manifest.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { PluginPackageManifest } from "@web3api/core-js"; - -export const manifest: PluginPackageManifest = { - // TODO: use the schema.graphql - // https://github.com/Web3-API/prototype/issues/101 - schema: `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! -}`, - implements: [], -}; diff --git a/packages/js/plugins/sha3/src/resolvers.ts b/packages/js/plugins/sha3/src/resolvers.ts index 6c1bb52c49..79f00b12f1 100644 --- a/packages/js/plugins/sha3/src/resolvers.ts +++ b/packages/js/plugins/sha3/src/resolvers.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { PluginModule } from "@web3api/core-js"; +import { Query } from "./w3"; + import { sha3_512, sha3_384, @@ -13,29 +14,29 @@ import { shake_256, } from "js-sha3"; -export const query = (): PluginModule => ({ - sha3_512: (input: { message: string }) => { +export const query = (): Query.Module => ({ + sha3_512: (input: Query.Input_sha3_512) => { return sha3_512(input.message); }, - sha3_384: (input: { message: string }) => { + sha3_384: (input: Query.Input_sha3_384) => { return sha3_384(input.message); }, - sha3_256: (input: { message: string }) => { + sha3_256: (input: Query.Input_sha3_256) => { return sha3_256(input.message); }, - sha3_224: (input: { message: string }) => { + sha3_224: (input: Query.Input_sha3_224) => { return sha3_224(input.message); }, - keccak_512: (input: { message: string }) => { + keccak_512: (input: Query.Input_keccak_512) => { return keccak_512(input.message); }, - keccak_384: (input: { message: string }) => { + keccak_384: (input: Query.Input_keccak_384) => { return keccak_384(input.message); }, - keccak_256: (input: { message: string }) => { + keccak_256: (input: Query.Input_keccak_256) => { return keccak_256(input.message); }, - hex_keccak_256: (input: { message: string }) => { + hex_keccak_256: (input: Query.Input_hex_keccak_256) => { // remove the leading 0x const hexString = input.message.replace(/^0x/, ""); @@ -66,16 +67,16 @@ export const query = (): PluginModule => ({ return keccak_256(new Uint8Array(integers)); }, - buffer_keccak_256: (input: { message: ArrayBuffer }) => { + buffer_keccak_256: (input: Query.Input_buffer_keccak_256) => { return keccak_256(input.message); }, - keccak_224: (input: { message: string }) => { + keccak_224: (input: Query.Input_keccak_224) => { return keccak_224(input.message); }, - shake_128: (input: { message: string; outputBits: number }) => { + shake_128: (input: Query.Input_shake_128) => { return shake_128(input.message, input.outputBits); }, - shake_256: (input: { message: string; outputBits: number }) => { + shake_256: (input: Query.Input_shake_256) => { return shake_256(input.message, input.outputBits); }, }); diff --git a/packages/js/plugins/sha3/web3api.plugin.yaml b/packages/js/plugins/sha3/web3api.plugin.yaml new file mode 100644 index 0000000000..b21359a846 --- /dev/null +++ b/packages/js/plugins/sha3/web3api.plugin.yaml @@ -0,0 +1,3 @@ +format: 0.0.1-prealpha.1 +language: plugin/typescript +schema: ./schema.graphql diff --git a/packages/js/plugins/uts46/package.json b/packages/js/plugins/uts46/package.json index e343bee06a..f6b6ac4933 100644 --- a/packages/js/plugins/uts46/package.json +++ b/packages/js/plugins/uts46/package.json @@ -13,7 +13,8 @@ "schema.graphql" ], "scripts": { - "build": "rimraf build && tsc --project tsconfig.build.json", + "build": "rimraf ./build && yarn codegen && tsc --project tsconfig.build.json", + "codegen": "npx -p @web3api/cli w3 plugin codegen", "lint": "eslint --color --ext .ts --ignore-pattern **/*.js src/", "test": "jest --passWithNoTests --runInBand --verbose", "test:ci": "jest --passWithNoTests --runInBand --verbose", diff --git a/packages/js/plugins/uts46/schema.graphql b/packages/js/plugins/uts46/schema.graphql index 207badeade..40bf75cf99 100644 --- a/packages/js/plugins/uts46/schema.graphql +++ b/packages/js/plugins/uts46/schema.graphql @@ -1,5 +1,10 @@ type Query { toAscii(value: String!): String! toUnicode(value: String!): String! - convert(value: String!): String! -} \ No newline at end of file + convert(value: String!): ConvertResult! +} + +type ConvertResult { + IDN: String! + PC: String! +} diff --git a/packages/js/plugins/uts46/src/index.ts b/packages/js/plugins/uts46/src/index.ts index 8409903c2d..702dee6c9e 100644 --- a/packages/js/plugins/uts46/src/index.ts +++ b/packages/js/plugins/uts46/src/index.ts @@ -1,10 +1,9 @@ -import { manifest } from "./manifest"; +import { manifest, Query } from "./w3"; import { query } from "./resolvers"; import { Plugin, PluginPackageManifest, - PluginModules, PluginPackage, } from "@web3api/core-js"; @@ -13,7 +12,9 @@ export class UTS46Plugin extends Plugin { return manifest; } - getModules(): PluginModules { + getModules(): { + query: Query.Module, + } { return { query: query(), }; diff --git a/packages/js/plugins/uts46/src/manifest.ts b/packages/js/plugins/uts46/src/manifest.ts deleted file mode 100644 index d90f51927b..0000000000 --- a/packages/js/plugins/uts46/src/manifest.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { PluginPackageManifest } from "@web3api/core-js"; - -export const manifest: PluginPackageManifest = { - // TODO: use the schema.graphql - // https://github.com/Web3-API/prototype/issues/101 - schema: `type Query { - toAscii(value: String!): String! - toUnicode(value: String!): String! - convert(value: String!): String! -}`, - implements: [], -}; diff --git a/packages/js/plugins/uts46/src/resolvers.ts b/packages/js/plugins/uts46/src/resolvers.ts index bc9bd706a0..314779d15a 100644 --- a/packages/js/plugins/uts46/src/resolvers.ts +++ b/packages/js/plugins/uts46/src/resolvers.ts @@ -1,14 +1,14 @@ -import { PluginModule } from "@web3api/core-js"; +import { Query } from "./w3"; import uts46 from "idna-uts46-hx"; -export const query = (): PluginModule => ({ - toAscii: (input: { value: string }) => { +export const query = (): Query.Module => ({ + toAscii: (input: Query.Input_toAscii) => { return uts46.toAscii(input.value); }, - toUnicode: (input: { value: string }) => { + toUnicode: (input: Query.Input_toUnicode) => { return uts46.toUnicode(input.value); }, - convert: (input: { value: string }) => { + convert: (input: Query.Input_convert) => { return uts46.convert(input.value); }, }); diff --git a/packages/js/plugins/uts46/web3api.plugin.yaml b/packages/js/plugins/uts46/web3api.plugin.yaml new file mode 100644 index 0000000000..b21359a846 --- /dev/null +++ b/packages/js/plugins/uts46/web3api.plugin.yaml @@ -0,0 +1,3 @@ +format: 0.0.1-prealpha.1 +language: plugin/typescript +schema: ./schema.graphql