From 776e2dcd9f7bae7af6d30ea358dd0c314323002b Mon Sep 17 00:00:00 2001 From: dafuga Date: Thu, 27 Jun 2024 19:43:33 -0700 Subject: [PATCH] fix: fixing PR checks --- .eslintignore | 2 + .eslintrc | 27 ++++++++++ .github/workflows/test.yml | 15 ++---- .prettierc | 10 ++++ Makefile | 4 +- bun.lockb | Bin 44674 -> 85738 bytes package.json | 56 +++++++++++--------- src/chains.ts | 70 ++++++++++++------------- src/index.ts | 98 +++++++++++++++++++---------------- src/types.ts | 9 ++++ tests/index.test.ts | 102 +++++++++++++++++++------------------ 11 files changed, 225 insertions(+), 168 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 .prettierc create mode 100644 src/types.ts diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..f06235c --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..718a8f7 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,27 @@ +{ + "root": true, + "ignorePatterns": ["dist/*", "node_modules/**"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended" + ], + "rules": { + "prettier/prettier": "warn", + "no-console": "warn", + "sort-imports": [ + "warn", + { + "ignoreCase": true, + "ignoreDeclarationSort": true + } + ], + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-empty-function": "warn", + "no-inner-declarations": "off" + } +} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b3cd44e..a55ac34 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,7 +6,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [14, 16, 18] + node-version: [16, 18] name: Node.js v${{ matrix.node-version }} steps: - name: Setup Node.js @@ -18,20 +18,13 @@ jobs: uses: actions/checkout@v2 - name: Install Bun - run: | - curl -fsSL https://bun.sh/install | bash - echo 'export BUN_INSTALL="$HOME/.bun"' >> $GITHUB_ENV - echo 'export PATH="$BUN_INSTALL/bin:$PATH"' >> $GITHUB_ENV - source $GITHUB_ENV - - - name: Verify Bun installation - run: bun --version + uses: oven-sh/setup-bun@v1 - name: Install dependencies run: bun install - name: Run checks - run: bun run make check + run: make check - name: Run tests - run: bun run make test + run: make test diff --git a/.prettierc b/.prettierc new file mode 100644 index 0000000..edd8a7b --- /dev/null +++ b/.prettierc @@ -0,0 +1,10 @@ +arrowParens: 'always' +bracketSpacing: false +endOfLine: 'lf' +printWidth: 100 +semi: false +singleQuote: true +tabWidth: 4 +useTabs: true +trailingComma: 'es5' +parser: typescript diff --git a/Makefile b/Makefile index 90eef1a..9e1b1cd 100644 --- a/Makefile +++ b/Makefile @@ -16,11 +16,11 @@ test: build node_modules .PHONY: check check: node_modules - @${BIN}/eslint src --ext .ts --max-warnings 0 --format unix && echo "Ok" + @${BIN}/eslint src tests --max-warnings 0 --format unix && echo "Ok" .PHONY: format format: node_modules - @${BIN}/eslint src --ext .ts --fix + @${BIN}/eslint src tests --ext .ts --fix .PHONY: distclean distclean: clean diff --git a/bun.lockb b/bun.lockb index f67bd4c8c9df24b41bad02a129a83eab859f4ec1..3906377df8069c338a9485c613bd7e58357d5d73 100755 GIT binary patch literal 85738 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 q^(@Ezb { - const url = new URL(req.url); - const key = url.pathname.split("/")[2]; - const includeTestnets = url.searchParams.get("includeTestnets") === "true"; + const url = new URL(req.url); + const key = url.pathname.split('/')[2]; + const includeTestnets = url.searchParams.get('includeTestnets') === 'true'; - let publicKey: PublicKey; + let publicKey: PublicKey; - try { - publicKey = PublicKey.from(key) - } catch (error) { - return new Response(JSON.stringify({ error: "Invalid public key" }), { status: 400 }); - } + try { + publicKey = PublicKey.from(key); + } catch (error) { + return new Response(JSON.stringify({ error: 'Invalid public key' }), { status: 400 }); + } - const chains: Chain[] = includeTestnets ? [...MAINNET_CHAINS, ...TESTNET_CHAINS] : MAINNET_CHAINS; - const lookups = (await Promise.all(chains.map(chain => lookupNetwork(publicKey, chain)))).filter(({ accounts }) => accounts.length > 0) + const chains: Chain[] = includeTestnets ? [...MAINNET_CHAINS, ...TESTNET_CHAINS] : MAINNET_CHAINS; + const lookups = ( + await Promise.all(chains.map((chain) => lookupNetwork(publicKey, chain))) + ).filter(({ accounts }) => accounts.length > 0); - const networkAccounts = lookups.map(({ chain, accounts }) => ({ - network: chain.name, - chainId: chain.id, - accounts, - })); + const networkAccounts = lookups.map(({ chain, accounts }) => ({ + network: chain.name, + chainId: chain.id, + accounts + })); - const totalAccounts = networkAccounts.reduce((total, { accounts }) => total + accounts.length, 0); - console.log(`Found ${totalAccounts} auth(s) across ${networkAccounts.length} network(s)`); + const totalAccounts = networkAccounts.reduce((total, { accounts }) => total + accounts.length, 0); + log(`Found ${totalAccounts} auth(s) across ${networkAccounts.length} network(s)`); - return new Response(JSON.stringify(networkAccounts)); + return new Response(JSON.stringify(networkAccounts)); }; export const lookupNetwork = async (publicKey: PublicKey, chain: Chain, apiClient?: APIClient) => { - try { - const accounts = await networkRequest(publicKey, chain, apiClient); - return { chain, accounts }; - } catch (error) { - console.warn(`Lookup error on ${chain.name}: ${error}`); - return { chain, accounts: [] };; - } + try { + const accounts = await networkRequest(publicKey, chain, apiClient); + return { chain, accounts }; + } catch (error) { + log(`Lookup error on ${chain.name}: ${error}`); + return { chain, accounts: [] }; + } }; const networkRequest = async (publicKey: PublicKey, chain: Chain, apiClient?: APIClient) => { - const client = apiClient || new APIClient(chain); - const response = await client.v1.chain.get_accounts_by_authorizers({ keys: [publicKey] }); - return response.accounts.map((account: any) => ({ - actor: account.account_name, - permission: account.permission_name, - })); + const client = apiClient || new APIClient(chain); + const response: API.v1.AccountsByAuthorizers = await client.v1.chain.get_accounts_by_authorizers({ + keys: [publicKey] + }); + return response.accounts.map((account) => ({ + actor: account.account_name, + permission: account.permission_name + })); }; +function log(message: string) { + // eslint-disable-next-line no-console + console.warn(message); +} + serve({ - fetch(req: Request) { - const url = new URL(req.url); - if (url.pathname.startsWith("/lookup")) { - return accountLookup(req); - } + fetch(req: Request) { + const url = new URL(req.url); + if (url.pathname.startsWith('/lookup')) { + return accountLookup(req); + } - return new Response("💡🏠", { status: 200 }); - }, - port: 3000, + return new Response('💡🏠', { status: 200 }); + }, + port: 3000 }); -console.log('Server running at http://localhost:3000/ 🚀') \ No newline at end of file +log('Server running at http://localhost:3000/ 🚀'); diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..6a5cc10 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,9 @@ +import type { ChainDefinition } from '@wharfkit/common'; + +export type Chain = + | ChainDefinition + | { + id: string; + name: string; + url: string; + }; diff --git a/tests/index.test.ts b/tests/index.test.ts index cec2420..9b9e767 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -1,58 +1,62 @@ import { assert } from 'chai'; -import { PublicKey } from "@wharfkit/antelope"; -import { Chains } from "@wharfkit/common"; -import { lookupNetwork, accountLookup } from '../src/index'; +import { PublicKey } from '@wharfkit/antelope'; +import { Chains } from '@wharfkit/common'; +import { accountLookup, lookupNetwork } from '../src/index'; import { makeClient } from '@wharfkit/mock-data'; -const PUBLIC_KEY = 'EOS65BFgzcH8uZW837HqadGcREfNViBV6Fqc1LsmwcWdfUCayHQzf' -const NON_EXISTENT_PUBLIC_KEY = 'EOS8hiZaTNknE75KH2UmBNqcVFN4u3vgJ8PcytevjygaJ6aGWfb7U' -const BAD_PUBLIC_KEY = 'EOS6KybFkAb54UMSvHoj4BMGTKPd21GEw3HUCoB5uc1vabasasqYrV' +const PUBLIC_KEY = 'EOS65BFgzcH8uZW837HqadGcREfNViBV6Fqc1LsmwcWdfUCayHQzf'; +const NON_EXISTENT_PUBLIC_KEY = 'EOS8hiZaTNknE75KH2UmBNqcVFN4u3vgJ8PcytevjygaJ6aGWfb7U'; +const BAD_PUBLIC_KEY = 'EOS6KybFkAb54UMSvHoj4BMGTKPd21GEw3HUCoB5uc1vabasasqYrV'; const mockClient = makeClient('https://jungle4.greymass.com'); -describe("accountLookup", () => { - it("should handle case where bad public key is provided", async () => { - const req = new Request(`https://eosio.greymass.com/lookup/${BAD_PUBLIC_KEY}`); - const result = await accountLookup(req); - assert.equal(result.status, 400); - }) - - it("should handle case where no public key is provided", async () => { - const req = new Request(`https://eosio.greymass.com/lookup/`); - const result = await accountLookup(req); - assert.equal(result.status, 400); - }) +describe('accountLookup', () => { + it('should handle case where bad public key is provided', async () => { + const req = new Request(`https://eosio.greymass.com/lookup/${BAD_PUBLIC_KEY}`); + const result = await accountLookup(req); + assert.equal(result.status, 400); + }); + + it('should handle case where no public key is provided', async () => { + const req = new Request(`https://eosio.greymass.com/lookup/`); + const result = await accountLookup(req); + assert.equal(result.status, 400); + }); }); -describe("lookupNetwork", () => { - it("should handle network lookup", async () => { - const publicKey = PublicKey.from(PUBLIC_KEY); - const chain = Chains.Jungle4; - - const result = await lookupNetwork(publicKey, Chains.Jungle4, mockClient); - assert.containsAllKeys(result, ['chain', 'accounts']); - assert.equal(result.chain.name, chain.name); - assert.equal(result.accounts.length, 2); - assert.deepEqual(String(result.accounts[0].actor), "testerman123"); - }); - - it("should handle network lookup with non existent public key", async () => { - const publicKey = PublicKey.from(NON_EXISTENT_PUBLIC_KEY); - const chain = Chains.Jungle4; - - const result = await lookupNetwork(publicKey, chain, mockClient); - assert.containsAllKeys(result, ['chain', 'accounts']); - assert.equal(result.chain.name, chain.name); - assert.equal(result.accounts.length, 0); - }); - - it("should handle network lookup error", async () => { - const publicKey = PublicKey.from(PUBLIC_KEY); - const chain = Chains.Jungle4; - - const result = await lookupNetwork(publicKey, chain, makeClient('https://jungle0.greymass.com')); - assert.containsAllKeys(result, ['chain', 'accounts']); - assert.equal(result.chain.name, chain.name); - assert.equal(result.accounts.length, 0); - }); +describe('lookupNetwork', () => { + it('should handle network lookup', async () => { + const publicKey = PublicKey.from(PUBLIC_KEY); + const chain = Chains.Jungle4; + + const result = await lookupNetwork(publicKey, Chains.Jungle4, mockClient); + assert.containsAllKeys(result, ['chain', 'accounts']); + assert.equal(result.chain.name, chain.name); + assert.equal(result.accounts.length, 2); + assert.deepEqual(String(result.accounts[0].actor), 'testerman123'); + }); + + it('should handle network lookup with non existent public key', async () => { + const publicKey = PublicKey.from(NON_EXISTENT_PUBLIC_KEY); + const chain = Chains.Jungle4; + + const result = await lookupNetwork(publicKey, chain, mockClient); + assert.containsAllKeys(result, ['chain', 'accounts']); + assert.equal(result.chain.name, chain.name); + assert.equal(result.accounts.length, 0); + }); + + it('should handle network lookup error', async () => { + const publicKey = PublicKey.from(PUBLIC_KEY); + const chain = Chains.Jungle4; + + const result = await lookupNetwork( + publicKey, + chain, + makeClient('https://jungle0.greymass.com') + ); + assert.containsAllKeys(result, ['chain', 'accounts']); + assert.equal(result.chain.name, chain.name); + assert.equal(result.accounts.length, 0); + }); });