Skip to content

Commit 3781bbb

Browse files
authored
chore: refactor getAction (#2429)
* chore: refactor getAction * Create grumpy-cycles-drop.md
1 parent f9d4ead commit 3781bbb

File tree

3 files changed

+46
-15
lines changed

3 files changed

+46
-15
lines changed

.changeset/grumpy-cycles-drop.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"viem": patch
3+
---
4+
5+
Fixed an issue where `getAction` would ignore nullish return values from a synchronous Client Action.

src/utils/getAction.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ test('uses client action', async () => {
3232
expect(clientSpy).toBeCalledWith({})
3333
})
3434

35+
test('nullish return value', async () => {
36+
const foo = () => null
37+
const foo_2 = () => true
38+
const client_2 = client.extend(() => ({
39+
foo,
40+
}))
41+
const result = getAction(client_2, foo_2, 'foo')({})
42+
expect(result).toEqual(null)
43+
})
44+
3545
test('e2e', async () => {
3646
const client_2 = client.extend(() => ({
3747
async call() {

src/utils/getAction.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
import type { Client } from '../clients/createClient.js'
2+
import type { PublicActions } from '../clients/decorators/public.js'
3+
import type { WalletActions } from '../clients/decorators/wallet.js'
4+
import type { Transport } from '../clients/transports/createTransport.js'
5+
import type { Account } from '../types/account.js'
6+
import type { Chain } from '../types/chain.js'
7+
import type { RpcSchema } from '../types/eip1193.js'
28

39
/**
410
* Retrieves and returns an action from the client (if exists), and falls
@@ -7,20 +13,30 @@ import type { Client } from '../clients/createClient.js'
713
* Useful for extracting overridden actions from a client (ie. if a consumer
814
* wants to override the `sendTransaction` implementation).
915
*/
10-
export function getAction<params extends {}, returnType extends {}>(
11-
client: Client,
12-
action: (_: any, params: params) => returnType,
13-
// Some minifiers drop `Function.prototype.name` or can change function
14-
// names so that getting the name by reflection through `action.name` will
15-
// not work.
16-
name: string,
17-
) {
18-
type DecoratedClient = Client & {
19-
[key: string]: (params: params) => returnType
20-
}
16+
export function getAction<
17+
transport extends Transport,
18+
chain extends Chain | undefined,
19+
account extends Account | undefined,
20+
rpcSchema extends RpcSchema | undefined,
21+
extended extends { [key: string]: unknown },
22+
client extends Client<transport, chain, account, rpcSchema, extended>,
23+
parameters,
24+
returnType,
25+
>(
26+
client: client,
27+
actionFn: (_: any, parameters: parameters) => returnType,
28+
// Some minifiers drop `Function.prototype.name`, or replace it with short letters,
29+
// meaning that `actionFn.name` will not always work. For that case, the consumer
30+
// needs to pass the name explicitly.
31+
name: keyof PublicActions | keyof WalletActions | (string & {}),
32+
): (parameters: parameters) => returnType {
33+
const action_implicit = client[actionFn.name]
34+
if (typeof action_implicit === 'function')
35+
return action_implicit as (params: parameters) => returnType
2136

22-
return (params: params): returnType =>
23-
(client as DecoratedClient)[action.name]?.(params) ??
24-
(client as DecoratedClient)[name]?.(params) ??
25-
action(client, params)
37+
const action_explicit = client[name]
38+
if (typeof action_explicit === 'function')
39+
return action_explicit as (params: parameters) => returnType
40+
41+
return (params) => actionFn(client, params)
2642
}

0 commit comments

Comments
 (0)