@codama/renderers-js 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/index.node.cjs +110 -95
  2. package/dist/index.node.cjs.map +1 -1
  3. package/dist/index.node.mjs +112 -97
  4. package/dist/index.node.mjs.map +1 -1
  5. package/dist/types/fragments/accountFetchHelpers.d.ts +2 -1
  6. package/dist/types/fragments/accountFetchHelpers.d.ts.map +1 -1
  7. package/dist/types/fragments/accountPdaHelpers.d.ts +3 -3
  8. package/dist/types/fragments/accountPdaHelpers.d.ts.map +1 -1
  9. package/dist/types/fragments/accountSizeHelpers.d.ts +2 -1
  10. package/dist/types/fragments/accountSizeHelpers.d.ts.map +1 -1
  11. package/dist/types/fragments/accountType.d.ts +2 -1
  12. package/dist/types/fragments/accountType.d.ts.map +1 -1
  13. package/dist/types/fragments/instructionAccountTypeParam.d.ts +3 -4
  14. package/dist/types/fragments/instructionAccountTypeParam.d.ts.map +1 -1
  15. package/dist/types/fragments/instructionByteDelta.d.ts +2 -1
  16. package/dist/types/fragments/instructionByteDelta.d.ts.map +1 -1
  17. package/dist/types/fragments/instructionData.d.ts +2 -1
  18. package/dist/types/fragments/instructionData.d.ts.map +1 -1
  19. package/dist/types/fragments/instructionExtraArgs.d.ts +2 -1
  20. package/dist/types/fragments/instructionExtraArgs.d.ts.map +1 -1
  21. package/dist/types/fragments/instructionFunction.d.ts +3 -4
  22. package/dist/types/fragments/instructionFunction.d.ts.map +1 -1
  23. package/dist/types/fragments/instructionInputDefault.d.ts.map +1 -1
  24. package/dist/types/fragments/instructionInputResolved.d.ts +2 -2
  25. package/dist/types/fragments/instructionInputResolved.d.ts.map +1 -1
  26. package/dist/types/fragments/instructionInputType.d.ts +2 -2
  27. package/dist/types/fragments/instructionInputType.d.ts.map +1 -1
  28. package/dist/types/fragments/instructionParseFunction.d.ts +3 -3
  29. package/dist/types/fragments/instructionParseFunction.d.ts.map +1 -1
  30. package/dist/types/fragments/instructionRemainingAccounts.d.ts +2 -1
  31. package/dist/types/fragments/instructionRemainingAccounts.d.ts.map +1 -1
  32. package/dist/types/fragments/instructionType.d.ts +3 -3
  33. package/dist/types/fragments/instructionType.d.ts.map +1 -1
  34. package/dist/types/fragments/pdaFunction.d.ts +3 -3
  35. package/dist/types/fragments/pdaFunction.d.ts.map +1 -1
  36. package/dist/types/getRenderMapVisitor.d.ts.map +1 -1
  37. package/dist/types/getTypeManifestVisitor.d.ts +2 -5
  38. package/dist/types/getTypeManifestVisitor.d.ts.map +1 -1
  39. package/dist/types/renderVisitor.d.ts.map +1 -1
  40. package/package.json +7 -7
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ var visitorsCore = require('@codama/visitors-core');
3
4
  var path = require('path');
4
5
  var nodes = require('@codama/nodes');
5
- var visitorsCore = require('@codama/visitors-core');
6
6
  var codecsStrings = require('@solana/codecs-strings');
7
7
  var errors = require('@codama/errors');
8
8
  require('url');
@@ -424,7 +424,8 @@ var Fragment = class _Fragment {
424
424
 
425
425
  // src/fragments/accountFetchHelpers.ts
426
426
  function getAccountFetchHelpersFragment(scope) {
427
- const { accountNode, typeManifest: typeManifest2, nameApi, customAccountData } = scope;
427
+ const { accountPath, typeManifest: typeManifest2, nameApi, customAccountData } = scope;
428
+ const accountNode = visitorsCore.getLastNodeFromPath(accountPath);
428
429
  const hasCustomData = customAccountData.has(accountNode.name);
429
430
  const accountTypeFragment = hasCustomData ? typeManifest2.strictType.clone() : fragment(nameApi.dataType(accountNode.name));
430
431
  const decoderFunctionFragment = hasCustomData ? typeManifest2.decoder.clone() : fragment(`${nameApi.decoderFunction(accountNode.name)}()`);
@@ -451,8 +452,10 @@ function getAccountFetchHelpersFragment(scope) {
451
452
  ]);
452
453
  }
453
454
  function getAccountPdaHelpersFragment(scope) {
454
- const { accountNode, programNode, nameApi, linkables, customAccountData, typeManifest: typeManifest2 } = scope;
455
- const pdaNode = accountNode.pda ? linkables.get(accountNode.pda) : void 0;
455
+ const { accountPath, nameApi, linkables, customAccountData, typeManifest: typeManifest2 } = scope;
456
+ const accountNode = visitorsCore.getLastNodeFromPath(accountPath);
457
+ const programNode = visitorsCore.findProgramNodeFromPath(accountPath);
458
+ const pdaNode = accountNode.pda ? linkables.get([...accountPath, accountNode.pda]) : void 0;
456
459
  if (!pdaNode) {
457
460
  return fragment("");
458
461
  }
@@ -478,10 +481,9 @@ function getAccountPdaHelpersFragment(scope) {
478
481
  "type MaybeAccount"
479
482
  ]);
480
483
  }
481
-
482
- // src/fragments/accountSizeHelpers.ts
483
484
  function getAccountSizeHelpersFragment(scope) {
484
- const { accountNode, nameApi } = scope;
485
+ const { accountPath, nameApi } = scope;
486
+ const accountNode = visitorsCore.getLastNodeFromPath(accountPath);
485
487
  if (accountNode.size == null) {
486
488
  return fragment("");
487
489
  }
@@ -561,7 +563,8 @@ function getTypeWithCodecFragment(scope) {
561
563
 
562
564
  // src/fragments/accountType.ts
563
565
  function getAccountTypeFragment(scope) {
564
- const { accountNode, typeManifest: typeManifest2, nameApi, customAccountData } = scope;
566
+ const { accountPath, typeManifest: typeManifest2, nameApi, customAccountData } = scope;
567
+ const accountNode = visitorsCore.getLastNodeFromPath(accountPath);
565
568
  if (customAccountData.has(accountNode.name)) {
566
569
  return fragment("");
567
570
  }
@@ -632,7 +635,10 @@ function getInstructionAccountMetaFragment(instructionAccountNode) {
632
635
  return fragment(`ReadonlyAccount<${typeParam}>`).addImports("solanaInstructions", "type ReadonlyAccount");
633
636
  }
634
637
  function getInstructionAccountTypeParamFragment(scope) {
635
- const { instructionNode, instructionAccountNode, programNode, allowAccountMeta, linkables } = scope;
638
+ const { instructionAccountPath, allowAccountMeta, linkables } = scope;
639
+ const instructionAccountNode = visitorsCore.getLastNodeFromPath(instructionAccountPath);
640
+ const instructionNode = visitorsCore.findInstructionNodeFromPath(instructionAccountPath);
641
+ const programNode = visitorsCore.findProgramNodeFromPath(instructionAccountPath);
636
642
  const typeParam = `TAccount${nodes.pascalCase(instructionAccountNode.name)}`;
637
643
  const accountMeta = allowAccountMeta ? " | IAccountMeta<string>" : "";
638
644
  const imports = new ImportMap();
@@ -650,7 +656,7 @@ function getDefaultAddress(defaultValue, programId, linkables) {
650
656
  case "publicKeyValueNode":
651
657
  return `"${defaultValue.publicKey}"`;
652
658
  case "programLinkNode":
653
- const programNode = linkables.get(defaultValue);
659
+ const programNode = linkables.get([defaultValue]);
654
660
  return programNode ? `"${programNode.publicKey}"` : "string";
655
661
  case "programIdValueNode":
656
662
  return `"${programId}"`;
@@ -659,7 +665,7 @@ function getDefaultAddress(defaultValue, programId, linkables) {
659
665
  }
660
666
  }
661
667
  function getInstructionByteDeltaFragment(scope) {
662
- const { byteDeltas } = scope.instructionNode;
668
+ const { byteDeltas } = visitorsCore.getLastNodeFromPath(scope.instructionPath);
663
669
  const fragments = (byteDeltas ?? []).flatMap((r) => getByteDeltaFragment(r, scope));
664
670
  if (fragments.length === 0) return fragment("");
665
671
  return mergeFragments(
@@ -715,10 +721,9 @@ function getResolverValueNodeFragment(byteDelta, scope) {
715
721
  const functionName = scope.nameApi.resolverFunction(byteDelta.value.name);
716
722
  return fragment(`${awaitKeyword}${functionName}(resolverScope)`).addImports(scope.getImportFrom(byteDelta.value), functionName).addFeatures(["instruction:resolverScopeVariable"]);
717
723
  }
718
-
719
- // src/fragments/instructionData.ts
720
724
  function getInstructionDataFragment(scope) {
721
- const { instructionNode, dataArgsManifest, nameApi, customInstructionData } = scope;
725
+ const { instructionPath, dataArgsManifest, nameApi, customInstructionData } = scope;
726
+ const instructionNode = visitorsCore.getLastNodeFromPath(instructionPath);
722
727
  if (instructionNode.arguments.length === 0 || customInstructionData.has(instructionNode.name)) {
723
728
  return fragment("");
724
729
  }
@@ -775,10 +780,9 @@ function getConstantFragment(scope) {
775
780
  (r) => r.join("\n\n")
776
781
  );
777
782
  }
778
-
779
- // src/fragments/instructionExtraArgs.ts
780
783
  function getInstructionExtraArgsFragment(scope) {
781
- const { instructionNode, extraArgsManifest, nameApi } = scope;
784
+ const { instructionPath, extraArgsManifest, nameApi } = scope;
785
+ const instructionNode = visitorsCore.getLastNodeFromPath(instructionPath);
782
786
  if ((instructionNode.extraArguments ?? []).length === 0) {
783
787
  return fragment("");
784
788
  }
@@ -835,17 +839,16 @@ accounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`
835
839
  const pdaSeeds2 = defaultValue.pda.seeds.flatMap((seed) => {
836
840
  if (nodes.isNode(seed, "constantPdaSeedNode") && nodes.isNode(seed.value, "programIdValueNode")) {
837
841
  return [
838
- fragment(`getAddressEncoder().encode(${pdaProgram})`).mergeImportsWith(pdaProgram).addImports("solanaAddresses", "getAddressEncoder")
842
+ fragment(`getAddressEncoder().encode(${pdaProgram.render})`).mergeImportsWith(pdaProgram).addImports("solanaAddresses", "getAddressEncoder")
839
843
  ];
840
844
  }
841
845
  if (nodes.isNode(seed, "constantPdaSeedNode") && !nodes.isNode(seed.value, "programIdValueNode")) {
842
846
  const typeManifest2 = visitorsCore.visit(seed.type, typeManifestVisitor);
843
847
  const valueManifest2 = visitorsCore.visit(seed.value, typeManifestVisitor);
844
848
  return [
845
- fragment(`${typeManifest2.encoder}.encode(${valueManifest2.value})`).mergeImportsWith(
846
- typeManifest2.encoder,
847
- valueManifest2.value
848
- )
849
+ fragment(
850
+ `${typeManifest2.encoder.render}.encode(${valueManifest2.value.render})`
851
+ ).mergeImportsWith(typeManifest2.encoder, valueManifest2.value)
849
852
  ];
850
853
  }
851
854
  if (nodes.isNode(seed, "variablePdaSeedNode")) {
@@ -855,23 +858,22 @@ accounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`
855
858
  if (nodes.isNode(valueSeed, "accountValueNode")) {
856
859
  return [
857
860
  fragment(
858
- `${typeManifest2.encoder}.encode(expectAddress(accounts.${nodes.camelCase(valueSeed.name)}.value))`
861
+ `${typeManifest2.encoder.render}.encode(expectAddress(accounts.${nodes.camelCase(valueSeed.name)}.value))`
859
862
  ).mergeImportsWith(typeManifest2.encoder).addImports("shared", "expectAddress")
860
863
  ];
861
864
  }
862
865
  if (nodes.isNode(valueSeed, "argumentValueNode")) {
863
866
  return [
864
867
  fragment(
865
- `${typeManifest2.encoder}.encode(expectSome(args.${nodes.camelCase(valueSeed.name)}))`
868
+ `${typeManifest2.encoder.render}.encode(expectSome(args.${nodes.camelCase(valueSeed.name)}))`
866
869
  ).mergeImportsWith(typeManifest2.encoder).addImports("shared", "expectSome")
867
870
  ];
868
871
  }
869
872
  const valueManifest2 = visitorsCore.visit(valueSeed, typeManifestVisitor);
870
873
  return [
871
- fragment(`${typeManifest2.encoder}.encode(${valueManifest2.value})`).mergeImportsWith(
872
- typeManifest2.encoder,
873
- valueManifest2.value
874
- )
874
+ fragment(
875
+ `${typeManifest2.encoder.render}.encode(${valueManifest2.value.render})`
876
+ ).mergeImportsWith(typeManifest2.encoder, valueManifest2.value)
875
877
  ];
876
878
  }
877
879
  return [];
@@ -1000,11 +1002,12 @@ function renderNestedInstructionDefault(scope) {
1000
1002
 
1001
1003
  // src/fragments/instructionInputResolved.ts
1002
1004
  function getInstructionInputResolvedFragment(scope) {
1005
+ const instructionNode = visitorsCore.getLastNodeFromPath(scope.instructionPath);
1003
1006
  const resolvedInputFragments = scope.resolvedInputs.flatMap((input) => {
1004
1007
  const inputFragment = getInstructionInputDefaultFragment({
1005
1008
  ...scope,
1006
1009
  input,
1007
- optionalAccountStrategy: scope.instructionNode.optionalAccountStrategy
1010
+ optionalAccountStrategy: instructionNode.optionalAccountStrategy
1008
1011
  });
1009
1012
  if (!inputFragment.render) return [];
1010
1013
  const camelName = nodes.camelCase(input.name);
@@ -1027,7 +1030,8 @@ ${r}
1027
1030
  );
1028
1031
  }
1029
1032
  function getInstructionInputTypeFragment(scope) {
1030
- const { instructionNode, useAsync, nameApi } = scope;
1033
+ const { instructionPath, useAsync, nameApi } = scope;
1034
+ const instructionNode = visitorsCore.getLastNodeFromPath(instructionPath);
1031
1035
  const instructionInputType = useAsync ? nameApi.instructionAsyncInputType(instructionNode.name) : nameApi.instructionSyncInputType(instructionNode.name);
1032
1036
  const accountsFragment = getAccountsFragment(scope);
1033
1037
  const [dataArgumentsFragment, customDataArgumentsFragment] = getDataArgumentsFragments(scope);
@@ -1050,7 +1054,8 @@ function getInstructionInputTypeFragment(scope) {
1050
1054
  ).addImports("solanaAddresses", ["type Address"]);
1051
1055
  }
1052
1056
  function getAccountsFragment(scope) {
1053
- const { instructionNode, resolvedInputs, useAsync, asyncResolvers } = scope;
1057
+ const { instructionPath, resolvedInputs, useAsync, asyncResolvers } = scope;
1058
+ const instructionNode = visitorsCore.getLastNodeFromPath(instructionPath);
1054
1059
  const fragments = instructionNode.accounts.map((account) => {
1055
1060
  const resolvedAccount = resolvedInputs.find(
1056
1061
  (input) => input.kind === "instructionAccountNode" && input.name === account.name
@@ -1083,7 +1088,8 @@ function getAccountTypeFragment2(account) {
1083
1088
  return fragment(`Address<${typeParam}>`).addImports("solanaAddresses", ["type Address"]);
1084
1089
  }
1085
1090
  function getDataArgumentsFragments(scope) {
1086
- const { instructionNode, nameApi } = scope;
1091
+ const { instructionPath, nameApi } = scope;
1092
+ const instructionNode = visitorsCore.getLastNodeFromPath(instructionPath);
1087
1093
  const customData = scope.customInstructionData.get(instructionNode.name);
1088
1094
  if (customData) {
1089
1095
  return [
@@ -1100,7 +1106,8 @@ function getDataArgumentsFragments(scope) {
1100
1106
  return [mergeFragments(fragments, (r) => r.join("\n")), fragment("")];
1101
1107
  }
1102
1108
  function getExtraArgumentsFragment(scope) {
1103
- const { instructionNode, nameApi } = scope;
1109
+ const { instructionPath, nameApi } = scope;
1110
+ const instructionNode = visitorsCore.getLastNodeFromPath(instructionPath);
1104
1111
  const instructionExtraName = nameApi.instructionExtraType(instructionNode.name);
1105
1112
  const extraArgsType = nameApi.dataArgsType(instructionExtraName);
1106
1113
  const fragments = (instructionNode.extraArguments ?? []).flatMap((arg) => {
@@ -1139,7 +1146,7 @@ function getRemainingAccountsFragment(instructionNode) {
1139
1146
  return mergeFragments(fragments, (r) => r.join("\n"));
1140
1147
  }
1141
1148
  function getInstructionRemainingAccountsFragment(scope) {
1142
- const { remainingAccounts } = scope.instructionNode;
1149
+ const { remainingAccounts } = visitorsCore.getLastNodeFromPath(scope.instructionPath);
1143
1150
  const fragments = (remainingAccounts ?? []).flatMap((r) => getRemainingAccountsFragment2(r, scope));
1144
1151
  if (fragments.length === 0) return fragment("");
1145
1152
  return mergeFragments(
@@ -1162,7 +1169,7 @@ function getRemainingAccountsFragment2(remainingAccounts, scope) {
1162
1169
  return [remainingAccountsFragment];
1163
1170
  }
1164
1171
  function getArgumentValueNodeFragment2(remainingAccounts, scope) {
1165
- const { instructionNode } = scope;
1172
+ const instructionNode = visitorsCore.getLastNodeFromPath(scope.instructionPath);
1166
1173
  nodes.assertIsNode(remainingAccounts.value, "argumentValueNode");
1167
1174
  const argumentName = nodes.camelCase(remainingAccounts.value.name);
1168
1175
  const isOptional = remainingAccounts.isOptional ?? false;
@@ -1205,8 +1212,7 @@ function getResolverValueNodeFragment2(remainingAccounts, scope) {
1205
1212
  function getInstructionFunctionFragment(scope) {
1206
1213
  const {
1207
1214
  useAsync,
1208
- instructionNode,
1209
- programNode,
1215
+ instructionPath,
1210
1216
  resolvedInputs,
1211
1217
  renamedArgs,
1212
1218
  dataArgsManifest,
@@ -1214,6 +1220,8 @@ function getInstructionFunctionFragment(scope) {
1214
1220
  nameApi,
1215
1221
  customInstructionData
1216
1222
  } = scope;
1223
+ const instructionNode = visitorsCore.getLastNodeFromPath(instructionPath);
1224
+ const programNode = visitorsCore.findProgramNodeFromPath(instructionPath);
1217
1225
  if (useAsync && !hasAsyncFunction(instructionNode, resolvedInputs, asyncResolvers)) {
1218
1226
  return fragment("");
1219
1227
  }
@@ -1315,7 +1323,8 @@ function getTypeParams(instructionNode, programAddressConstant) {
1315
1323
  return fragment(typeParams.filter((x) => !!x).join(", ")).mapRender((r) => `<${r}>`).addImports("generatedPrograms", [programAddressConstant]);
1316
1324
  }
1317
1325
  function getInstructionType(scope) {
1318
- const { instructionNode, nameApi } = scope;
1326
+ const { instructionPath, nameApi } = scope;
1327
+ const instructionNode = visitorsCore.getLastNodeFromPath(instructionPath);
1319
1328
  const instructionTypeName = nameApi.instructionType(instructionNode.name);
1320
1329
  const programAddressFragment = fragment("TProgramAddress");
1321
1330
  const accountTypeParamsFragments = instructionNode.accounts.map((account) => {
@@ -1335,16 +1344,17 @@ function getInstructionType(scope) {
1335
1344
  ).mapRender((r) => `${instructionTypeName}<${r}>`);
1336
1345
  }
1337
1346
  function getInputTypeCall(scope) {
1338
- const { instructionNode, useAsync, nameApi } = scope;
1347
+ const { instructionPath, useAsync, nameApi } = scope;
1348
+ const instructionNode = visitorsCore.getLastNodeFromPath(instructionPath);
1339
1349
  const inputTypeName = useAsync ? nameApi.instructionAsyncInputType(instructionNode.name) : nameApi.instructionSyncInputType(instructionNode.name);
1340
1350
  if (instructionNode.accounts.length === 0) return fragment(inputTypeName);
1341
1351
  const accountTypeParams = instructionNode.accounts.map((account) => `TAccount${nodes.pascalCase(account.name)}`).join(", ");
1342
1352
  return fragment(`${inputTypeName}<${accountTypeParams}>`);
1343
1353
  }
1344
-
1345
- // src/fragments/instructionParseFunction.ts
1346
1354
  function getInstructionParseFunctionFragment(scope) {
1347
- const { instructionNode, programNode, dataArgsManifest, nameApi, customInstructionData } = scope;
1355
+ const { instructionPath, dataArgsManifest, nameApi, customInstructionData } = scope;
1356
+ const instructionNode = visitorsCore.getLastNodeFromPath(instructionPath);
1357
+ const programNode = visitorsCore.findProgramNodeFromPath(instructionPath);
1348
1358
  const customData = customInstructionData.get(instructionNode.name);
1349
1359
  const hasAccounts = instructionNode.accounts.length > 0;
1350
1360
  const hasOptionalAccounts = instructionNode.accounts.some((account) => account.isOptional);
@@ -1373,7 +1383,9 @@ function getInstructionParseFunctionFragment(scope) {
1373
1383
  }).mergeImportsWith(dataTypeFragment).addImports("generatedPrograms", [programAddressConstant]).addImports("solanaInstructions", ["type IInstruction"]).addImports("solanaInstructions", hasAccounts ? ["type IInstructionWithAccounts", "type IAccountMeta"] : []).addImports("solanaInstructions", hasData ? ["type IInstructionWithData"] : []);
1374
1384
  }
1375
1385
  function getInstructionTypeFragment(scope) {
1376
- const { instructionNode, programNode, nameApi, customInstructionData } = scope;
1386
+ const { instructionPath, nameApi, customInstructionData } = scope;
1387
+ const instructionNode = visitorsCore.getLastNodeFromPath(instructionPath);
1388
+ const programNode = visitorsCore.findProgramNodeFromPath(instructionPath);
1377
1389
  const hasAccounts = instructionNode.accounts.length > 0;
1378
1390
  const customData = customInstructionData.get(instructionNode.name);
1379
1391
  const hasData = !!customData || instructionNode.arguments.length > 0;
@@ -1385,7 +1397,7 @@ function getInstructionTypeFragment(scope) {
1385
1397
  (account) => getInstructionAccountTypeParamFragment({
1386
1398
  ...scope,
1387
1399
  allowAccountMeta: true,
1388
- instructionAccountNode: account
1400
+ instructionAccountPath: [...instructionPath, account]
1389
1401
  })
1390
1402
  ),
1391
1403
  (renders) => renders.join(", ")
@@ -1421,7 +1433,9 @@ function getInstructionTypeFragment(scope) {
1421
1433
  return fragment2;
1422
1434
  }
1423
1435
  function getPdaFunctionFragment(scope) {
1424
- const { pdaNode, programNode, typeManifestVisitor, nameApi } = scope;
1436
+ const { pdaPath, typeManifestVisitor, nameApi } = scope;
1437
+ const pdaNode = visitorsCore.getLastNodeFromPath(pdaPath);
1438
+ const programNode = visitorsCore.findProgramNodeFromPath(pdaPath);
1425
1439
  const imports = new ImportMap();
1426
1440
  const seeds = pdaNode.seeds.map((seed) => {
1427
1441
  if (nodes.isNode(seed, "variablePdaSeedNode")) {
@@ -1640,8 +1654,8 @@ function mergeManifests(manifests, options = {}) {
1640
1654
  }
1641
1655
  function getTypeManifestVisitor(input) {
1642
1656
  const { nameApi, linkables, nonScalarEnums, customAccountData, customInstructionData, getImportFrom } = input;
1643
- const stack = new visitorsCore.NodeStack();
1644
- let parentName = input.parentName ?? null;
1657
+ const stack = input.stack ?? new visitorsCore.NodeStack();
1658
+ let parentName = null;
1645
1659
  return visitorsCore.pipe(
1646
1660
  visitorsCore.staticVisitor(
1647
1661
  () => ({
@@ -1652,14 +1666,16 @@ function getTypeManifestVisitor(input) {
1652
1666
  strictType: fragment(""),
1653
1667
  value: fragment("")
1654
1668
  }),
1655
- [
1656
- ...nodes.REGISTERED_TYPE_NODE_KINDS,
1657
- ...nodes.REGISTERED_VALUE_NODE_KINDS,
1658
- "definedTypeLinkNode",
1659
- "definedTypeNode",
1660
- "accountNode",
1661
- "instructionNode"
1662
- ]
1669
+ {
1670
+ keys: [
1671
+ ...nodes.REGISTERED_TYPE_NODE_KINDS,
1672
+ ...nodes.REGISTERED_VALUE_NODE_KINDS,
1673
+ "definedTypeLinkNode",
1674
+ "definedTypeNode",
1675
+ "accountNode",
1676
+ "instructionNode"
1677
+ ]
1678
+ }
1663
1679
  ),
1664
1680
  (visitor) => visitorsCore.extendVisitor(visitor, {
1665
1681
  visitAccount(account, { self }) {
@@ -1904,7 +1920,7 @@ function getTypeManifestVisitor(input) {
1904
1920
  const enumName = nameApi.dataType(node.enum.name);
1905
1921
  const enumFunction = nameApi.discriminatedUnionFunction(node.enum.name);
1906
1922
  const importFrom = getImportFrom(node.enum);
1907
- const enumNode = linkables.get(node.enum)?.type;
1923
+ const enumNode = linkables.get([...stack.getPath(), node.enum])?.type;
1908
1924
  const isScalar = enumNode && nodes.isNode(enumNode, "enumTypeNode") ? nodes.isScalarEnum(enumNode) : !nonScalarEnums.includes(node.enum.name);
1909
1925
  if (!node.value && isScalar) {
1910
1926
  const variantName2 = nameApi.enumVariant(node.variant);
@@ -1928,19 +1944,19 @@ function getTypeManifestVisitor(input) {
1928
1944
  visitHiddenPrefixType(node, { self }) {
1929
1945
  const manifest = visitorsCore.visit(node.type, self);
1930
1946
  const prefixes = node.prefix.map((c) => visitorsCore.visit(c, self).value);
1931
- const prefixEncoders = fragment(prefixes.map((c) => `getConstantEncoder(${c})`).join(", ")).addImports("solanaCodecsCore", "getConstantEncoder").mergeImportsWith(...prefixes);
1932
- const prefixDecoders = fragment(prefixes.map((c) => `getConstantDecoder(${c})`).join(", ")).addImports("solanaCodecsCore", "getConstantDecoder").mergeImportsWith(...prefixes);
1933
- manifest.encoder.mapRender((r) => `getHiddenPrefixEncoder(${r}, [${prefixEncoders}])`).mergeImportsWith(prefixEncoders).addImports("solanaCodecsDataStructures", "getHiddenPrefixEncoder");
1934
- manifest.decoder.mapRender((r) => `getHiddenPrefixDecoder(${r}, [${prefixDecoders}])`).mergeImportsWith(prefixDecoders).addImports("solanaCodecsDataStructures", "getHiddenPrefixDecoder");
1947
+ const prefixEncoders = fragment(prefixes.map((c) => `getConstantEncoder(${c.render})`).join(", ")).addImports("solanaCodecsCore", "getConstantEncoder").mergeImportsWith(...prefixes);
1948
+ const prefixDecoders = fragment(prefixes.map((c) => `getConstantDecoder(${c.render})`).join(", ")).addImports("solanaCodecsCore", "getConstantDecoder").mergeImportsWith(...prefixes);
1949
+ manifest.encoder.mapRender((r) => `getHiddenPrefixEncoder(${r}, [${prefixEncoders.render}])`).mergeImportsWith(prefixEncoders).addImports("solanaCodecsDataStructures", "getHiddenPrefixEncoder");
1950
+ manifest.decoder.mapRender((r) => `getHiddenPrefixDecoder(${r}, [${prefixDecoders.render}])`).mergeImportsWith(prefixDecoders).addImports("solanaCodecsDataStructures", "getHiddenPrefixDecoder");
1935
1951
  return manifest;
1936
1952
  },
1937
1953
  visitHiddenSuffixType(node, { self }) {
1938
1954
  const manifest = visitorsCore.visit(node.type, self);
1939
1955
  const suffixes = node.suffix.map((c) => visitorsCore.visit(c, self).value);
1940
- const suffixEncoders = fragment(suffixes.map((c) => `getConstantEncoder(${c})`).join(", ")).addImports("solanaCodecsCore", "getConstantEncoder").mergeImportsWith(...suffixes);
1941
- const suffixDecoders = fragment(suffixes.map((c) => `getConstantDecoder(${c})`).join(", ")).addImports("solanaCodecsCore", "getConstantDecoder").mergeImportsWith(...suffixes);
1942
- manifest.encoder.mapRender((r) => `getHiddenSuffixEncoder(${r}, [${suffixEncoders}])`).mergeImportsWith(suffixEncoders).addImports("solanaCodecsDataStructures", "getHiddenSuffixEncoder");
1943
- manifest.decoder.mapRender((r) => `getHiddenSuffixDecoder(${r}, [${suffixDecoders}])`).mergeImportsWith(suffixDecoders).addImports("solanaCodecsDataStructures", "getHiddenSuffixDecoder");
1956
+ const suffixEncoders = fragment(suffixes.map((c) => `getConstantEncoder(${c.render})`).join(", ")).addImports("solanaCodecsCore", "getConstantEncoder").mergeImportsWith(...suffixes);
1957
+ const suffixDecoders = fragment(suffixes.map((c) => `getConstantDecoder(${c.render})`).join(", ")).addImports("solanaCodecsCore", "getConstantDecoder").mergeImportsWith(...suffixes);
1958
+ manifest.encoder.mapRender((r) => `getHiddenSuffixEncoder(${r}, [${suffixEncoders.render}])`).mergeImportsWith(suffixEncoders).addImports("solanaCodecsDataStructures", "getHiddenSuffixEncoder");
1959
+ manifest.decoder.mapRender((r) => `getHiddenSuffixDecoder(${r}, [${suffixDecoders.render}])`).mergeImportsWith(suffixDecoders).addImports("solanaCodecsDataStructures", "getHiddenSuffixDecoder");
1944
1960
  return manifest;
1945
1961
  },
1946
1962
  visitInstruction(instruction, { self }) {
@@ -2108,8 +2124,8 @@ function getTypeManifestVisitor(input) {
2108
2124
  visitSentinelType(node, { self }) {
2109
2125
  const manifest = visitorsCore.visit(node.type, self);
2110
2126
  const sentinel = visitorsCore.visit(node.sentinel, self).value;
2111
- manifest.encoder.mapRender((r) => `addEncoderSentinel(${r}, ${sentinel})`).mergeImportsWith(sentinel).addImports("solanaCodecsCore", "addEncoderSentinel");
2112
- manifest.decoder.mapRender((r) => `addDecoderSentinel(${r}, ${sentinel})`).mergeImportsWith(sentinel).addImports("solanaCodecsCore", "addDecoderSentinel");
2127
+ manifest.encoder.mapRender((r) => `addEncoderSentinel(${r}, ${sentinel.render})`).mergeImportsWith(sentinel).addImports("solanaCodecsCore", "addEncoderSentinel");
2128
+ manifest.decoder.mapRender((r) => `addDecoderSentinel(${r}, ${sentinel.render})`).mergeImportsWith(sentinel).addImports("solanaCodecsCore", "addDecoderSentinel");
2113
2129
  return manifest;
2114
2130
  },
2115
2131
  visitSetType(setType, { self }) {
@@ -2132,8 +2148,8 @@ function getTypeManifestVisitor(input) {
2132
2148
  visitSizePrefixType(node, { self }) {
2133
2149
  const manifest = visitorsCore.visit(node.type, self);
2134
2150
  const prefix = visitorsCore.visit(node.prefix, self);
2135
- manifest.encoder.mapRender((r) => `addEncoderSizePrefix(${r}, ${prefix.encoder})`).mergeImportsWith(prefix.encoder).addImports("solanaCodecsCore", "addEncoderSizePrefix");
2136
- manifest.decoder.mapRender((r) => `addDecoderSizePrefix(${r}, ${prefix.decoder})`).mergeImportsWith(prefix.decoder).addImports("solanaCodecsCore", "addDecoderSizePrefix");
2151
+ manifest.encoder.mapRender((r) => `addEncoderSizePrefix(${r}, ${prefix.encoder.render})`).mergeImportsWith(prefix.encoder).addImports("solanaCodecsCore", "addEncoderSizePrefix");
2152
+ manifest.decoder.mapRender((r) => `addDecoderSizePrefix(${r}, ${prefix.decoder.render})`).mergeImportsWith(prefix.decoder).addImports("solanaCodecsCore", "addDecoderSizePrefix");
2137
2153
  return manifest;
2138
2154
  },
2139
2155
  visitSolAmountType({ number }, { self }) {
@@ -2224,8 +2240,9 @@ ${jsDocblock(structFieldType.docs)}` : "";
2224
2240
  if (optionalFields.length === 0) {
2225
2241
  return mergedManifest;
2226
2242
  }
2227
- const instructionNode = stack.find("instructionNode");
2228
- const accountNode = stack.find("accountNode");
2243
+ const parentPath = stack.getPath();
2244
+ const instructionNode = visitorsCore.findLastNodeFromPath(parentPath, "instructionNode");
2245
+ const accountNode = visitorsCore.findLastNodeFromPath(parentPath, "accountNode");
2229
2246
  const discriminatorPrefix = instructionNode ? instructionNode.name : accountNode?.name;
2230
2247
  const discriminators = (instructionNode ? instructionNode.discriminators : accountNode?.discriminators) ?? [];
2231
2248
  const fieldDiscriminators = discriminators.filter(nodes.isNodeFilter("fieldDiscriminatorNode"));
@@ -2378,7 +2395,7 @@ var DEFAULT_NAME_TRANSFORMERS = {
2378
2395
  // src/getRenderMapVisitor.ts
2379
2396
  function getRenderMapVisitor(options = {}) {
2380
2397
  const linkables = new visitorsCore.LinkableDictionary();
2381
- let program = null;
2398
+ const stack = new visitorsCore.NodeStack();
2382
2399
  const nameTransformers = {
2383
2400
  ...DEFAULT_NAME_TRANSFORMERS,
2384
2401
  ...options.nameTransformers
@@ -2393,16 +2410,15 @@ function getRenderMapVisitor(options = {}) {
2393
2410
  const customAccountData = parseCustomDataOptions(options.customAccountData ?? [], "AccountData");
2394
2411
  const customInstructionData = parseCustomDataOptions(options.customInstructionData ?? [], "InstructionData");
2395
2412
  const getImportFrom = getImportFromFactory(options.linkOverrides ?? {}, customAccountData, customInstructionData);
2396
- const getTypeManifestVisitor2 = (parentName) => getTypeManifestVisitor({
2413
+ const typeManifestVisitor = getTypeManifestVisitor({
2397
2414
  customAccountData,
2398
2415
  customInstructionData,
2399
2416
  getImportFrom,
2400
2417
  linkables,
2401
2418
  nameApi,
2402
2419
  nonScalarEnums,
2403
- parentName
2420
+ stack
2404
2421
  });
2405
- const typeManifestVisitor = getTypeManifestVisitor2();
2406
2422
  const resolvedInstructionInputVisitor = visitorsCore.getResolvedInstructionInputsVisitor();
2407
2423
  const globalScope = {
2408
2424
  asyncResolvers,
@@ -2419,19 +2435,18 @@ function getRenderMapVisitor(options = {}) {
2419
2435
  return render(path.join("pages", template), context, renderOptions);
2420
2436
  };
2421
2437
  return visitorsCore.pipe(
2422
- visitorsCore.staticVisitor(
2423
- () => new renderersCore.RenderMap(),
2424
- ["rootNode", "programNode", "pdaNode", "accountNode", "definedTypeNode", "instructionNode"]
2425
- ),
2438
+ visitorsCore.staticVisitor(() => new renderersCore.RenderMap(), {
2439
+ keys: ["rootNode", "programNode", "pdaNode", "accountNode", "definedTypeNode", "instructionNode"]
2440
+ }),
2426
2441
  (v) => visitorsCore.extendVisitor(v, {
2427
2442
  visitAccount(node) {
2428
- if (!program) {
2443
+ const accountPath = stack.getPath("accountNode");
2444
+ if (!visitorsCore.findProgramNodeFromPath(accountPath)) {
2429
2445
  throw new Error("Account must be visited inside a program.");
2430
2446
  }
2431
2447
  const scope = {
2432
2448
  ...globalScope,
2433
- accountNode: node,
2434
- programNode: program,
2449
+ accountPath,
2435
2450
  typeManifest: visitorsCore.visit(node, typeManifestVisitor)
2436
2451
  };
2437
2452
  const fields = nodes.resolveNestedTypeNode(node.data).fields;
@@ -2497,7 +2512,8 @@ function getRenderMapVisitor(options = {}) {
2497
2512
  );
2498
2513
  },
2499
2514
  visitInstruction(node) {
2500
- if (!program) {
2515
+ const instructionPath = stack.getPath("instructionNode");
2516
+ if (!visitorsCore.findProgramNodeFromPath(instructionPath)) {
2501
2517
  throw new Error("Instruction must be visited inside a program.");
2502
2518
  }
2503
2519
  const instructionExtraName = nameApi.instructionExtraType(node.name);
@@ -2505,14 +2521,13 @@ function getRenderMapVisitor(options = {}) {
2505
2521
  ...globalScope,
2506
2522
  dataArgsManifest: visitorsCore.visit(node, typeManifestVisitor),
2507
2523
  extraArgsManifest: visitorsCore.visit(
2508
- nodes.structTypeNodeFromInstructionArgumentNodes(node.extraArguments ?? []),
2509
- getTypeManifestVisitor2({
2510
- loose: nameApi.dataArgsType(instructionExtraName),
2511
- strict: nameApi.dataType(instructionExtraName)
2512
- })
2524
+ nodes.definedTypeNode({
2525
+ name: instructionExtraName,
2526
+ type: nodes.structTypeNodeFromInstructionArgumentNodes(node.extraArguments ?? [])
2527
+ }),
2528
+ typeManifestVisitor
2513
2529
  ),
2514
- instructionNode: node,
2515
- programNode: program,
2530
+ instructionPath,
2516
2531
  renamedArgs: getRenamedArgsMap(node),
2517
2532
  resolvedInputs: visitorsCore.visit(node, resolvedInstructionInputVisitor)
2518
2533
  };
@@ -2559,10 +2574,11 @@ function getRenderMapVisitor(options = {}) {
2559
2574
  );
2560
2575
  },
2561
2576
  visitPda(node) {
2562
- if (!program) {
2577
+ const pdaPath = stack.getPath("pdaNode");
2578
+ if (!visitorsCore.findProgramNodeFromPath(pdaPath)) {
2563
2579
  throw new Error("Account must be visited inside a program.");
2564
2580
  }
2565
- const scope = { ...globalScope, pdaNode: node, programNode: program };
2581
+ const scope = { ...globalScope, pdaPath };
2566
2582
  const pdaFunctionFragment = getPdaFunctionFragment(scope);
2567
2583
  const imports = new ImportMap().mergeWith(pdaFunctionFragment);
2568
2584
  return new renderersCore.RenderMap().add(
@@ -2574,7 +2590,6 @@ function getRenderMapVisitor(options = {}) {
2574
2590
  );
2575
2591
  },
2576
2592
  visitProgram(node, { self }) {
2577
- program = node;
2578
2593
  const customDataDefinedType = [
2579
2594
  ...getDefinedTypeNodesToExtract(node.accounts, customAccountData),
2580
2595
  ...getDefinedTypeNodesToExtract(node.instructions, customInstructionData)
@@ -2604,11 +2619,10 @@ function getRenderMapVisitor(options = {}) {
2604
2619
  })
2605
2620
  );
2606
2621
  renderMap.mergeWith(
2607
- ...nodes.getAllInstructionsWithSubs(program, {
2622
+ ...nodes.getAllInstructionsWithSubs(node, {
2608
2623
  leavesOnly: !renderParentInstructions
2609
2624
  }).map((ix) => visitorsCore.visit(ix, self))
2610
2625
  );
2611
- program = null;
2612
2626
  return renderMap;
2613
2627
  },
2614
2628
  visitRoot(node, { self }) {
@@ -2675,7 +2689,8 @@ function getRenderMapVisitor(options = {}) {
2675
2689
  return map.add("index.ts", render2("rootIndex.njk", ctx)).mergeWith(...nodes.getAllPrograms(node).map((p) => visitorsCore.visit(p, self)));
2676
2690
  }
2677
2691
  }),
2678
- (v) => visitorsCore.recordLinkablesVisitor(v, linkables)
2692
+ (v) => visitorsCore.recordNodeStackVisitor(v, stack),
2693
+ (v) => visitorsCore.recordLinkablesOnFirstVisitVisitor(v, linkables)
2679
2694
  );
2680
2695
  }
2681
2696
  function getRenamedArgsMap(instruction) {