Skip to content

Commit 2702bbe

Browse files
committed
Use NodePaths in renderers-js
1 parent 77fa128 commit 2702bbe

16 files changed

+110
-76
lines changed

packages/renderers-js/src/fragments/accountFetchHelpers.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import { AccountNode } from '@codama/nodes';
2+
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';
23

34
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
45
import { TypeManifest } from '../TypeManifest';
56
import { Fragment, fragment, fragmentFromTemplate } from './common';
67

78
export function getAccountFetchHelpersFragment(
89
scope: Pick<GlobalFragmentScope, 'customAccountData' | 'nameApi'> & {
9-
accountNode: AccountNode;
10+
accountPath: NodePath<AccountNode>;
1011
typeManifest: TypeManifest;
1112
},
1213
): Fragment {
13-
const { accountNode, typeManifest, nameApi, customAccountData } = scope;
14+
const { accountPath, typeManifest, nameApi, customAccountData } = scope;
15+
const accountNode = getLastNodeFromPath(accountPath);
1416
const hasCustomData = customAccountData.has(accountNode.name);
1517
const accountTypeFragment = hasCustomData
1618
? typeManifest.strictType.clone()

packages/renderers-js/src/fragments/accountPdaHelpers.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
import { AccountNode, isNodeFilter } from '@codama/nodes';
2-
import { NodeStack } from '@codama/visitors-core';
2+
import { findProgramNodeFromPath, getLastNodeFromPath, NodePath } from '@codama/visitors-core';
33

44
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
55
import type { TypeManifest } from '../TypeManifest';
66
import { Fragment, fragment, fragmentFromTemplate } from './common';
77

88
export function getAccountPdaHelpersFragment(
99
scope: Pick<GlobalFragmentScope, 'customAccountData' | 'linkables' | 'nameApi'> & {
10-
accountNode: AccountNode;
11-
accountStack: NodeStack;
10+
accountPath: NodePath<AccountNode>;
1211
typeManifest: TypeManifest;
1312
},
1413
): Fragment {
15-
const { accountNode, accountStack, nameApi, linkables, customAccountData, typeManifest } = scope;
16-
const pdaNode = accountNode.pda ? linkables.get([...accountStack.getPath(), accountNode.pda]) : undefined;
14+
const { accountPath, nameApi, linkables, customAccountData, typeManifest } = scope;
15+
const accountNode = getLastNodeFromPath(accountPath);
16+
const programNode = findProgramNodeFromPath(accountPath)!;
17+
const pdaNode = accountNode.pda ? linkables.get([...accountPath, accountNode.pda]) : undefined;
1718
if (!pdaNode) {
1819
return fragment('');
1920
}
@@ -39,7 +40,7 @@ export function getAccountPdaHelpersFragment(
3940
findPdaFunction,
4041
hasVariableSeeds,
4142
pdaSeedsType,
42-
program: accountStack.getProgram(),
43+
program: programNode,
4344
})
4445
.mergeImportsWith(accountTypeFragment)
4546
.addImports(importFrom, hasVariableSeeds ? [pdaSeedsType, findPdaFunction] : [findPdaFunction])

packages/renderers-js/src/fragments/accountSizeHelpers.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { AccountNode } from '@codama/nodes';
2+
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';
23

34
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
45
import { Fragment, fragment, fragmentFromTemplate } from './common';
56

67
export function getAccountSizeHelpersFragment(
7-
scope: Pick<GlobalFragmentScope, 'nameApi'> & { accountNode: AccountNode },
8+
scope: Pick<GlobalFragmentScope, 'nameApi'> & { accountPath: NodePath<AccountNode> },
89
): Fragment {
9-
const { accountNode, nameApi } = scope;
10+
const { accountPath, nameApi } = scope;
11+
const accountNode = getLastNodeFromPath(accountPath);
1012
if (accountNode.size == null) {
1113
return fragment('');
1214
}

packages/renderers-js/src/fragments/accountType.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { AccountNode } from '@codama/nodes';
2+
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';
23

34
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
45
import { TypeManifest } from '../TypeManifest';
@@ -7,11 +8,12 @@ import { getTypeWithCodecFragment } from './typeWithCodec';
78

89
export function getAccountTypeFragment(
910
scope: Pick<GlobalFragmentScope, 'customAccountData' | 'nameApi'> & {
10-
accountNode: AccountNode;
11+
accountPath: NodePath<AccountNode>;
1112
typeManifest: TypeManifest;
1213
},
1314
): Fragment {
14-
const { accountNode, typeManifest, nameApi, customAccountData } = scope;
15+
const { accountPath, typeManifest, nameApi, customAccountData } = scope;
16+
const accountNode = getLastNodeFromPath(accountPath);
1517

1618
if (customAccountData.has(accountNode.name)) {
1719
return fragment('');

packages/renderers-js/src/fragments/instructionAccountTypeParam.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
import { InstructionAccountNode, InstructionInputValueNode, InstructionNode, pascalCase } from '@codama/nodes';
2-
import { LinkableDictionary, NodeStack } from '@codama/visitors-core';
1+
import { InstructionAccountNode, InstructionInputValueNode, pascalCase } from '@codama/nodes';
2+
import {
3+
findInstructionNodeFromPath,
4+
findProgramNodeFromPath,
5+
getLastNodeFromPath,
6+
LinkableDictionary,
7+
NodePath,
8+
} from '@codama/visitors-core';
39

410
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
511
import { ImportMap } from '../ImportMap';
@@ -8,12 +14,13 @@ import { Fragment, fragment } from './common';
814
export function getInstructionAccountTypeParamFragment(
915
scope: Pick<GlobalFragmentScope, 'linkables'> & {
1016
allowAccountMeta: boolean;
11-
instructionAccountNode: InstructionAccountNode;
12-
instructionNode: InstructionNode;
13-
instructionStack: NodeStack;
17+
instructionAccountPath: NodePath<InstructionAccountNode>;
1418
},
1519
): Fragment {
16-
const { instructionNode, instructionAccountNode, instructionStack, allowAccountMeta, linkables } = scope;
20+
const { instructionAccountPath, allowAccountMeta, linkables } = scope;
21+
const instructionAccountNode = getLastNodeFromPath(instructionAccountPath);
22+
const instructionNode = findInstructionNodeFromPath(instructionAccountPath)!;
23+
const programNode = findProgramNodeFromPath(instructionAccountPath)!;
1724
const typeParam = `TAccount${pascalCase(instructionAccountNode.name)}`;
1825
const accountMeta = allowAccountMeta ? ' | IAccountMeta<string>' : '';
1926
const imports = new ImportMap();
@@ -25,11 +32,7 @@ export function getInstructionAccountTypeParamFragment(
2532
return fragment(`${typeParam} extends string${accountMeta} | undefined = undefined`, imports);
2633
}
2734

28-
const defaultAddress = getDefaultAddress(
29-
instructionAccountNode.defaultValue,
30-
instructionStack.getProgram()!.publicKey,
31-
linkables,
32-
);
35+
const defaultAddress = getDefaultAddress(instructionAccountNode.defaultValue, programNode.publicKey, linkables);
3336

3437
return fragment(`${typeParam} extends string${accountMeta} = ${defaultAddress}`, imports);
3538
}

packages/renderers-js/src/fragments/instructionByteDelta.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import { assertIsNode, camelCase, InstructionByteDeltaNode, InstructionNode, isNode } from '@codama/nodes';
2+
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';
23

34
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
45
import { Fragment, fragment, mergeFragments } from './common';
56

67
export function getInstructionByteDeltaFragment(
78
scope: Pick<GlobalFragmentScope, 'asyncResolvers' | 'getImportFrom' | 'nameApi'> & {
8-
instructionNode: InstructionNode;
9+
instructionPath: NodePath<InstructionNode>;
910
useAsync: boolean;
1011
},
1112
): Fragment {
12-
const { byteDeltas } = scope.instructionNode;
13+
const { byteDeltas } = getLastNodeFromPath(scope.instructionPath);
1314
const fragments = (byteDeltas ?? []).flatMap(r => getByteDeltaFragment(r, scope));
1415
if (fragments.length === 0) return fragment('');
1516
return mergeFragments(

packages/renderers-js/src/fragments/instructionData.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { InstructionNode } from '@codama/nodes';
2+
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';
23

34
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
45
import { TypeManifest } from '../TypeManifest';
@@ -8,10 +9,11 @@ import { getTypeWithCodecFragment } from './typeWithCodec';
89
export function getInstructionDataFragment(
910
scope: Pick<GlobalFragmentScope, 'customInstructionData' | 'nameApi'> & {
1011
dataArgsManifest: TypeManifest;
11-
instructionNode: InstructionNode;
12+
instructionPath: NodePath<InstructionNode>;
1213
},
1314
): Fragment {
14-
const { instructionNode, dataArgsManifest, nameApi, customInstructionData } = scope;
15+
const { instructionPath, dataArgsManifest, nameApi, customInstructionData } = scope;
16+
const instructionNode = getLastNodeFromPath(instructionPath);
1517
if (instructionNode.arguments.length === 0 || customInstructionData.has(instructionNode.name)) {
1618
return fragment('');
1719
}

packages/renderers-js/src/fragments/instructionExtraArgs.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { InstructionNode } from '@codama/nodes';
2+
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';
23

34
import { GlobalFragmentScope } from '../getRenderMapVisitor';
45
import { TypeManifest } from '../TypeManifest';
@@ -7,10 +8,11 @@ import { Fragment, fragment, fragmentFromTemplate } from './common';
78
export function getInstructionExtraArgsFragment(
89
scope: Pick<GlobalFragmentScope, 'nameApi'> & {
910
extraArgsManifest: TypeManifest;
10-
instructionNode: InstructionNode;
11+
instructionPath: NodePath<InstructionNode>;
1112
},
1213
): Fragment {
13-
const { instructionNode, extraArgsManifest, nameApi } = scope;
14+
const { instructionPath, extraArgsManifest, nameApi } = scope;
15+
const instructionNode = getLastNodeFromPath(instructionPath);
1416
if ((instructionNode.extraArguments ?? []).length === 0) {
1517
return fragment('');
1618
}

packages/renderers-js/src/fragments/instructionFunction.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { camelCase, InstructionArgumentNode, InstructionNode, isNode, isNodeFilter, pascalCase } from '@codama/nodes';
2-
import { NodeStack, ResolvedInstructionInput } from '@codama/visitors-core';
2+
import {
3+
findProgramNodeFromPath,
4+
getLastNodeFromPath,
5+
NodePath,
6+
ResolvedInstructionInput,
7+
} from '@codama/visitors-core';
38

49
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
510
import { NameApi } from '../nameTransformers';
@@ -18,24 +23,24 @@ export function getInstructionFunctionFragment(
1823
> & {
1924
dataArgsManifest: TypeManifest;
2025
extraArgsManifest: TypeManifest;
21-
instructionNode: InstructionNode;
22-
instructionStack: NodeStack;
26+
instructionPath: NodePath<InstructionNode>;
2327
renamedArgs: Map<string, string>;
2428
resolvedInputs: ResolvedInstructionInput[];
2529
useAsync: boolean;
2630
},
2731
): Fragment {
2832
const {
2933
useAsync,
30-
instructionNode,
31-
instructionStack,
34+
instructionPath,
3235
resolvedInputs,
3336
renamedArgs,
3437
dataArgsManifest,
3538
asyncResolvers,
3639
nameApi,
3740
customInstructionData,
3841
} = scope;
42+
const instructionNode = getLastNodeFromPath(instructionPath);
43+
const programNode = findProgramNodeFromPath(instructionPath)!;
3944
if (useAsync && !hasAsyncFunction(instructionNode, resolvedInputs, asyncResolvers)) {
4045
return fragment('');
4146
}
@@ -66,7 +71,7 @@ export function getInstructionFunctionFragment(
6671
const hasAnyArgs = hasDataArgs || hasExtraArgs || hasRemainingAccountArgs;
6772
const hasInput = hasAccounts || hasAnyArgs;
6873
const instructionDataName = nameApi.instructionDataType(instructionNode.name);
69-
const programAddressConstant = nameApi.programAddressConstant(instructionStack.getProgram()!.name);
74+
const programAddressConstant = nameApi.programAddressConstant(programNode.name);
7075
const encoderFunction = customData
7176
? dataArgsManifest.encoder.render
7277
: `${nameApi.encoderFunction(instructionDataName)}()`;
@@ -165,8 +170,9 @@ function getTypeParams(instructionNode: InstructionNode, programAddressConstant:
165170
.addImports('generatedPrograms', [programAddressConstant]);
166171
}
167172

168-
function getInstructionType(scope: { instructionNode: InstructionNode; nameApi: NameApi }): Fragment {
169-
const { instructionNode, nameApi } = scope;
173+
function getInstructionType(scope: { instructionPath: NodePath<InstructionNode>; nameApi: NameApi }): Fragment {
174+
const { instructionPath, nameApi } = scope;
175+
const instructionNode = getLastNodeFromPath(instructionPath);
170176
const instructionTypeName = nameApi.instructionType(instructionNode.name);
171177
const programAddressFragment = fragment('TProgramAddress');
172178
const accountTypeParamsFragments = instructionNode.accounts.map(account => {
@@ -192,8 +198,13 @@ function getInstructionType(scope: { instructionNode: InstructionNode; nameApi:
192198
).mapRender(r => `${instructionTypeName}<${r}>`);
193199
}
194200

195-
function getInputTypeCall(scope: { instructionNode: InstructionNode; nameApi: NameApi; useAsync: boolean }): Fragment {
196-
const { instructionNode, useAsync, nameApi } = scope;
201+
function getInputTypeCall(scope: {
202+
instructionPath: NodePath<InstructionNode>;
203+
nameApi: NameApi;
204+
useAsync: boolean;
205+
}): Fragment {
206+
const { instructionPath, useAsync, nameApi } = scope;
207+
const instructionNode = getLastNodeFromPath(instructionPath);
197208
const inputTypeName = useAsync
198209
? nameApi.instructionAsyncInputType(instructionNode.name)
199210
: nameApi.instructionSyncInputType(instructionNode.name);

packages/renderers-js/src/fragments/instructionInputResolved.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
import { camelCase, InstructionNode, isNode } from '@codama/nodes';
2-
import { ResolvedInstructionInput } from '@codama/visitors-core';
2+
import { getLastNodeFromPath, NodePath, ResolvedInstructionInput } from '@codama/visitors-core';
33

44
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
55
import { Fragment, fragment, mergeFragments } from './common';
66
import { getInstructionInputDefaultFragment } from './instructionInputDefault';
77

88
export function getInstructionInputResolvedFragment(
99
scope: Pick<GlobalFragmentScope, 'asyncResolvers' | 'getImportFrom' | 'nameApi' | 'typeManifestVisitor'> & {
10-
instructionNode: InstructionNode;
10+
instructionPath: NodePath<InstructionNode>;
1111
resolvedInputs: ResolvedInstructionInput[];
1212
useAsync: boolean;
1313
},
1414
): Fragment {
15+
const instructionNode = getLastNodeFromPath(scope.instructionPath);
1516
const resolvedInputFragments = scope.resolvedInputs.flatMap((input: ResolvedInstructionInput): Fragment[] => {
1617
const inputFragment = getInstructionInputDefaultFragment({
1718
...scope,
1819
input,
19-
optionalAccountStrategy: scope.instructionNode.optionalAccountStrategy,
20+
optionalAccountStrategy: instructionNode.optionalAccountStrategy,
2021
});
2122
if (!inputFragment.render) return [];
2223
const camelName = camelCase(input.name);

0 commit comments

Comments
 (0)