@codama/renderers-js 1.3.5 → 1.4.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 (156) hide show
  1. package/LICENSE +1 -1
  2. package/dist/index.browser.cjs +3247 -0
  3. package/dist/index.browser.cjs.map +1 -0
  4. package/dist/index.browser.mjs +3300 -0
  5. package/dist/index.browser.mjs.map +1 -0
  6. package/dist/index.node.cjs +1742 -1956
  7. package/dist/index.node.cjs.map +1 -1
  8. package/dist/index.node.mjs +1644 -1866
  9. package/dist/index.node.mjs.map +1 -1
  10. package/dist/index.react-native.mjs +3300 -0
  11. package/dist/index.react-native.mjs.map +1 -0
  12. package/dist/types/fragments/accountFetchHelpers.d.ts +2 -4
  13. package/dist/types/fragments/accountFetchHelpers.d.ts.map +1 -1
  14. package/dist/types/fragments/accountPage.d.ts +8 -0
  15. package/dist/types/fragments/accountPage.d.ts.map +1 -0
  16. package/dist/types/fragments/accountPdaHelpers.d.ts +3 -5
  17. package/dist/types/fragments/accountPdaHelpers.d.ts.map +1 -1
  18. package/dist/types/fragments/accountSizeHelpers.d.ts +3 -4
  19. package/dist/types/fragments/accountSizeHelpers.d.ts.map +1 -1
  20. package/dist/types/fragments/accountType.d.ts +3 -5
  21. package/dist/types/fragments/accountType.d.ts.map +1 -1
  22. package/dist/types/fragments/discriminatorCondition.d.ts +2 -3
  23. package/dist/types/fragments/discriminatorCondition.d.ts.map +1 -1
  24. package/dist/types/fragments/discriminatorConstants.d.ts +5 -6
  25. package/dist/types/fragments/discriminatorConstants.d.ts.map +1 -1
  26. package/dist/types/fragments/errorPage.d.ts +6 -0
  27. package/dist/types/fragments/errorPage.d.ts.map +1 -0
  28. package/dist/types/fragments/index.d.ts +11 -3
  29. package/dist/types/fragments/index.d.ts.map +1 -1
  30. package/dist/types/fragments/indexPage.d.ts +6 -0
  31. package/dist/types/fragments/indexPage.d.ts.map +1 -0
  32. package/dist/types/fragments/instructionAccountMeta.d.ts.map +1 -1
  33. package/dist/types/fragments/instructionAccountTypeParam.d.ts +2 -3
  34. package/dist/types/fragments/instructionAccountTypeParam.d.ts.map +1 -1
  35. package/dist/types/fragments/instructionByteDelta.d.ts +3 -4
  36. package/dist/types/fragments/instructionByteDelta.d.ts.map +1 -1
  37. package/dist/types/fragments/instructionData.d.ts +3 -5
  38. package/dist/types/fragments/instructionData.d.ts.map +1 -1
  39. package/dist/types/fragments/instructionExtraArgs.d.ts +3 -5
  40. package/dist/types/fragments/instructionExtraArgs.d.ts.map +1 -1
  41. package/dist/types/fragments/instructionFunction.d.ts +3 -5
  42. package/dist/types/fragments/instructionFunction.d.ts.map +1 -1
  43. package/dist/types/fragments/instructionInputDefault.d.ts +2 -3
  44. package/dist/types/fragments/instructionInputDefault.d.ts.map +1 -1
  45. package/dist/types/fragments/instructionInputResolved.d.ts +2 -3
  46. package/dist/types/fragments/instructionInputResolved.d.ts.map +1 -1
  47. package/dist/types/fragments/instructionInputType.d.ts +2 -4
  48. package/dist/types/fragments/instructionInputType.d.ts.map +1 -1
  49. package/dist/types/fragments/instructionPage.d.ts +9 -0
  50. package/dist/types/fragments/instructionPage.d.ts.map +1 -0
  51. package/dist/types/fragments/instructionParseFunction.d.ts +2 -4
  52. package/dist/types/fragments/instructionParseFunction.d.ts.map +1 -1
  53. package/dist/types/fragments/instructionRemainingAccounts.d.ts +3 -4
  54. package/dist/types/fragments/instructionRemainingAccounts.d.ts.map +1 -1
  55. package/dist/types/fragments/instructionType.d.ts +2 -3
  56. package/dist/types/fragments/instructionType.d.ts.map +1 -1
  57. package/dist/types/fragments/pdaFunction.d.ts +2 -3
  58. package/dist/types/fragments/pdaFunction.d.ts.map +1 -1
  59. package/dist/types/fragments/pdaPage.d.ts +7 -0
  60. package/dist/types/fragments/pdaPage.d.ts.map +1 -0
  61. package/dist/types/fragments/programAccounts.d.ts +3 -4
  62. package/dist/types/fragments/programAccounts.d.ts.map +1 -1
  63. package/dist/types/fragments/programConstant.d.ts +6 -0
  64. package/dist/types/fragments/programConstant.d.ts.map +1 -0
  65. package/dist/types/fragments/programInstructions.d.ts +3 -4
  66. package/dist/types/fragments/programInstructions.d.ts.map +1 -1
  67. package/dist/types/fragments/programPage.d.ts +6 -0
  68. package/dist/types/fragments/programPage.d.ts.map +1 -0
  69. package/dist/types/fragments/rootIndexPage.d.ts +10 -0
  70. package/dist/types/fragments/rootIndexPage.d.ts.map +1 -0
  71. package/dist/types/fragments/sharedPage.d.ts +3 -0
  72. package/dist/types/fragments/sharedPage.d.ts.map +1 -0
  73. package/dist/types/fragments/type.d.ts +2 -4
  74. package/dist/types/fragments/type.d.ts.map +1 -1
  75. package/dist/types/fragments/typeCodec.d.ts +2 -4
  76. package/dist/types/fragments/typeCodec.d.ts.map +1 -1
  77. package/dist/types/fragments/typeDecoder.d.ts +2 -4
  78. package/dist/types/fragments/typeDecoder.d.ts.map +1 -1
  79. package/dist/types/fragments/typeDiscriminatedUnionHelpers.d.ts +3 -4
  80. package/dist/types/fragments/typeDiscriminatedUnionHelpers.d.ts.map +1 -1
  81. package/dist/types/fragments/typeEncoder.d.ts +2 -4
  82. package/dist/types/fragments/typeEncoder.d.ts.map +1 -1
  83. package/dist/types/fragments/typePage.d.ts +7 -0
  84. package/dist/types/fragments/typePage.d.ts.map +1 -0
  85. package/dist/types/fragments/typeWithCodec.d.ts +2 -4
  86. package/dist/types/fragments/typeWithCodec.d.ts.map +1 -1
  87. package/dist/types/index.d.ts +5 -7
  88. package/dist/types/index.d.ts.map +1 -1
  89. package/dist/types/utils/fragment.d.ts +12 -8
  90. package/dist/types/utils/fragment.d.ts.map +1 -1
  91. package/dist/types/utils/importMap.d.ts +17 -0
  92. package/dist/types/utils/importMap.d.ts.map +1 -0
  93. package/dist/types/utils/index.d.ts +4 -1
  94. package/dist/types/utils/index.d.ts.map +1 -1
  95. package/dist/types/utils/nameTransformers.d.ts.map +1 -0
  96. package/dist/types/utils/options.d.ts +40 -0
  97. package/dist/types/utils/options.d.ts.map +1 -0
  98. package/dist/types/{TypeManifest.d.ts → utils/typeManifest.d.ts} +2 -2
  99. package/dist/types/utils/typeManifest.d.ts.map +1 -0
  100. package/dist/types/visitors/getRenderMapVisitor.d.ts +3 -0
  101. package/dist/types/visitors/getRenderMapVisitor.d.ts.map +1 -0
  102. package/dist/types/{getTypeManifestVisitor.d.ts → visitors/getTypeManifestVisitor.d.ts} +1 -2
  103. package/dist/types/visitors/getTypeManifestVisitor.d.ts.map +1 -0
  104. package/dist/types/visitors/index.d.ts +4 -0
  105. package/dist/types/visitors/index.d.ts.map +1 -0
  106. package/dist/types/visitors/renderVisitor.d.ts +3 -0
  107. package/dist/types/visitors/renderVisitor.d.ts.map +1 -0
  108. package/package.json +26 -21
  109. package/dist/templates/fragments/accountFetchHelpers.njk +0 -43
  110. package/dist/templates/fragments/accountPdaHelpers.njk +0 -25
  111. package/dist/templates/fragments/accountSizeHelpers.njk +0 -3
  112. package/dist/templates/fragments/instructionExtraArgs.njk +0 -4
  113. package/dist/templates/fragments/instructionFunction.njk +0 -62
  114. package/dist/templates/fragments/instructionInputType.njk +0 -16
  115. package/dist/templates/fragments/instructionParseFunction.njk +0 -81
  116. package/dist/templates/fragments/instructionType.njk +0 -18
  117. package/dist/templates/fragments/pdaFunction.njk +0 -33
  118. package/dist/templates/fragments/program.njk +0 -3
  119. package/dist/templates/fragments/programErrors.njk +0 -36
  120. package/dist/templates/fragments/type.njk +0 -12
  121. package/dist/templates/fragments/typeCodec.njk +0 -6
  122. package/dist/templates/fragments/typeDecoder.njk +0 -6
  123. package/dist/templates/fragments/typeDiscriminatedUnionHelpers.njk +0 -23
  124. package/dist/templates/fragments/typeEncoder.njk +0 -6
  125. package/dist/templates/layout.njk +0 -9
  126. package/dist/templates/macros.njk +0 -12
  127. package/dist/templates/pages/accountsIndex.njk +0 -9
  128. package/dist/templates/pages/accountsPage.njk +0 -12
  129. package/dist/templates/pages/definedTypesIndex.njk +0 -9
  130. package/dist/templates/pages/definedTypesPage.njk +0 -9
  131. package/dist/templates/pages/errorsIndex.njk +0 -9
  132. package/dist/templates/pages/errorsPage.njk +0 -8
  133. package/dist/templates/pages/instructionsIndex.njk +0 -9
  134. package/dist/templates/pages/instructionsPage.njk +0 -14
  135. package/dist/templates/pages/pdasIndex.njk +0 -9
  136. package/dist/templates/pages/pdasPage.njk +0 -8
  137. package/dist/templates/pages/programsIndex.njk +0 -9
  138. package/dist/templates/pages/programsPage.njk +0 -10
  139. package/dist/templates/pages/rootIndex.njk +0 -26
  140. package/dist/templates/pages/sharedPage.njk +0 -106
  141. package/dist/types/ImportMap.d.ts +0 -15
  142. package/dist/types/ImportMap.d.ts.map +0 -1
  143. package/dist/types/TypeManifest.d.ts.map +0 -1
  144. package/dist/types/fragments/program.d.ts +0 -7
  145. package/dist/types/fragments/program.d.ts.map +0 -1
  146. package/dist/types/fragments/programErrors.d.ts +0 -7
  147. package/dist/types/fragments/programErrors.d.ts.map +0 -1
  148. package/dist/types/getRenderMapVisitor.d.ts +0 -30
  149. package/dist/types/getRenderMapVisitor.d.ts.map +0 -1
  150. package/dist/types/getTypeManifestVisitor.d.ts.map +0 -1
  151. package/dist/types/nameTransformers.d.ts.map +0 -1
  152. package/dist/types/renderVisitor.d.ts +0 -11
  153. package/dist/types/renderVisitor.d.ts.map +0 -1
  154. package/dist/types/utils/render.d.ts +0 -4
  155. package/dist/types/utils/render.d.ts.map +0 -1
  156. /package/dist/types/{nameTransformers.d.ts → utils/nameTransformers.d.ts} +0 -0
@@ -1,4 +1,4 @@
1
- // src/ImportMap.ts
1
+ // src/utils/importMap.ts
2
2
  var DEFAULT_EXTERNAL_MODULE_MAP = {
3
3
  solanaAccounts: "@solana/kit",
4
4
  solanaAddresses: "@solana/kit",
@@ -40,97 +40,256 @@ var DEFAULT_INTERNAL_MODULE_MAP = {
40
40
  shared: "../shared",
41
41
  types: "../types"
42
42
  };
43
- var ImportMap = class {
44
- _imports = /* @__PURE__ */ new Map();
45
- _aliases = /* @__PURE__ */ new Map();
46
- add(module, imports) {
47
- const newImports = new Set(typeof imports === "string" ? [imports] : imports);
48
- if (newImports.size === 0) return this;
49
- const currentImports = this._imports.get(module) ?? /* @__PURE__ */ new Set();
50
- newImports.forEach((i) => currentImports.add(i));
51
- this._imports.set(module, currentImports);
52
- return this;
53
- }
54
- remove(module, imports) {
55
- const importsToRemove = new Set(typeof imports === "string" ? [imports] : imports);
56
- if (importsToRemove.size === 0) return this;
57
- const currentImports = this._imports.get(module) ?? /* @__PURE__ */ new Set();
58
- importsToRemove.forEach((i) => currentImports.delete(i));
59
- if (currentImports.size === 0) {
60
- this._imports.delete(module);
61
- } else {
62
- this._imports.set(module, currentImports);
63
- }
64
- return this;
65
- }
66
- mergeWith(...others) {
67
- others.forEach((rawOther) => {
68
- const other = "imports" in rawOther ? rawOther.imports : rawOther;
69
- other._imports.forEach((imports, module) => {
70
- this.add(module, imports);
71
- });
72
- other._aliases.forEach((aliases, module) => {
73
- Object.entries(aliases).forEach(([name, alias]) => {
74
- this.addAlias(module, name, alias);
75
- });
76
- });
77
- });
78
- return this;
79
- }
80
- mergeWithManifest(manifest) {
81
- return this.mergeWith(manifest.strictType, manifest.looseType, manifest.encoder, manifest.decoder);
82
- }
83
- addAlias(module, name, alias) {
84
- const currentAliases = this._aliases.get(module) ?? {};
85
- currentAliases[name] = alias;
86
- this._aliases.set(module, currentAliases);
87
- return this;
88
- }
89
- isEmpty() {
90
- return this._imports.size === 0;
91
- }
92
- resolve(dependencies = {}, useGranularImports = false) {
93
- const aliasedMap = new Map(
94
- [...this._imports.entries()].map(([module, imports]) => {
95
- const aliasMap = this._aliases.get(module) ?? {};
96
- const joinedImports = [...imports].map((i) => aliasMap[i] ? `${i} as ${aliasMap[i]}` : i);
97
- return [module, new Set(joinedImports)];
98
- })
99
- );
100
- const dependencyMap = {
101
- ...useGranularImports ? DEFAULT_GRANULAR_EXTERNAL_MODULE_MAP : DEFAULT_EXTERNAL_MODULE_MAP,
102
- ...DEFAULT_INTERNAL_MODULE_MAP,
103
- ...dependencies
104
- };
105
- const resolvedMap = /* @__PURE__ */ new Map();
106
- aliasedMap.forEach((imports, module) => {
107
- const resolvedModule = dependencyMap[module] ?? module;
108
- const currentImports = resolvedMap.get(resolvedModule) ?? /* @__PURE__ */ new Set();
109
- imports.forEach((i) => currentImports.add(i));
110
- resolvedMap.set(resolvedModule, currentImports);
111
- });
112
- return resolvedMap;
43
+ function createImportMap() {
44
+ return Object.freeze(/* @__PURE__ */ new Map());
45
+ }
46
+ function parseImportInput(input) {
47
+ const matches = input.match(/^(type )?([^ ]+)(?: as (.+))?$/);
48
+ if (!matches) return Object.freeze({ importedIdentifier: input, isType: false, usedIdentifier: input });
49
+ const [_, isType, name, alias] = matches;
50
+ return Object.freeze({
51
+ importedIdentifier: name,
52
+ isType: !!isType,
53
+ usedIdentifier: alias ?? name
54
+ });
55
+ }
56
+ function addToImportMap(importMap, module, imports) {
57
+ const parsedImports = imports.map(parseImportInput).map((i) => [i.usedIdentifier, i]);
58
+ return mergeImportMaps([importMap, /* @__PURE__ */ new Map([[module, new Map(parsedImports)]])]);
59
+ }
60
+ function removeFromImportMap(importMap, module, usedIdentifiers) {
61
+ const newMap = new Map(importMap);
62
+ const newModuleMap = new Map(newMap.get(module));
63
+ usedIdentifiers.forEach((usedIdentifier) => {
64
+ newModuleMap.delete(usedIdentifier);
65
+ });
66
+ if (newModuleMap.size === 0) {
67
+ newMap.delete(module);
68
+ } else {
69
+ newMap.set(module, newModuleMap);
113
70
  }
114
- toString(dependencies = {}, useGranularImports = false) {
115
- return [...this.resolve(dependencies, useGranularImports).entries()].sort(([a], [b]) => {
116
- const aIsRelative = a.startsWith(".");
117
- const bIsRelative = b.startsWith(".");
118
- if (aIsRelative && !bIsRelative) return 1;
119
- if (!aIsRelative && bIsRelative) return -1;
120
- return a.localeCompare(b);
121
- }).map(([module, imports]) => {
122
- const joinedImports = [...imports].sort().filter((i) => {
123
- const name = i.split(" ");
124
- if (name.length > 1) {
125
- return !imports.has(name[1]);
71
+ return Object.freeze(newMap);
72
+ }
73
+ function mergeImportMaps(importMaps) {
74
+ if (importMaps.length === 0) return createImportMap();
75
+ if (importMaps.length === 1) return importMaps[0];
76
+ const mergedMap = new Map(importMaps[0]);
77
+ for (const map of importMaps.slice(1)) {
78
+ for (const [module, imports] of map) {
79
+ const mergedModuleMap = mergedMap.get(module) ?? /* @__PURE__ */ new Map();
80
+ for (const [usedIdentifier, importInfo] of imports) {
81
+ const existingImportInfo = mergedModuleMap.get(usedIdentifier);
82
+ const shouldOverwriteTypeOnly = existingImportInfo && existingImportInfo.importedIdentifier === importInfo.importedIdentifier && existingImportInfo.isType && !importInfo.isType;
83
+ if (!existingImportInfo || shouldOverwriteTypeOnly) {
84
+ mergedModuleMap.set(usedIdentifier, importInfo);
126
85
  }
127
- return true;
128
- }).join(", ");
129
- return `import { ${joinedImports} } from '${module}';`;
130
- }).join("\n");
86
+ }
87
+ mergedMap.set(module, mergedModuleMap);
88
+ }
131
89
  }
90
+ return Object.freeze(mergedMap);
91
+ }
92
+ function importMapToString(importMap, dependencyMap = {}, useGranularImports = false) {
93
+ const resolvedMap = resolveImportMapModules(importMap, dependencyMap, useGranularImports);
94
+ return [...resolvedMap.entries()].sort(([a], [b]) => {
95
+ const relative = Number(a.startsWith(".")) - Number(b.startsWith("."));
96
+ if (relative !== 0) return relative;
97
+ return a.localeCompare(b);
98
+ }).map(([module, imports]) => {
99
+ const innerImports = [...imports.values()].map(importInfoToString).sort((a, b) => a.localeCompare(b)).join(", ");
100
+ return `import { ${innerImports} } from '${module}';`;
101
+ }).join("\n");
102
+ }
103
+ function resolveImportMapModules(importMap, dependencyMap, useGranularImports) {
104
+ const dependencyMapWithDefaults = {
105
+ ...useGranularImports ? DEFAULT_GRANULAR_EXTERNAL_MODULE_MAP : DEFAULT_EXTERNAL_MODULE_MAP,
106
+ ...DEFAULT_INTERNAL_MODULE_MAP,
107
+ ...dependencyMap
108
+ };
109
+ return mergeImportMaps(
110
+ [...importMap.entries()].map(([module, imports]) => {
111
+ const resolvedModule = dependencyMapWithDefaults[module] ?? module;
112
+ return /* @__PURE__ */ new Map([[resolvedModule, imports]]);
113
+ })
114
+ );
115
+ }
116
+ function importInfoToString({ importedIdentifier, isType, usedIdentifier }) {
117
+ const alias = importedIdentifier !== usedIdentifier ? ` as ${usedIdentifier}` : "";
118
+ return `${isType ? "type " : ""}${importedIdentifier}${alias}`;
119
+ }
120
+
121
+ // src/utils/nameTransformers.ts
122
+ import { camelCase, capitalize, kebabCase, pascalCase, snakeCase, titleCase } from "@codama/nodes";
123
+ function getNameApi(transformers) {
124
+ const helpers = {
125
+ camelCase,
126
+ capitalize,
127
+ kebabCase,
128
+ pascalCase,
129
+ snakeCase,
130
+ titleCase
131
+ };
132
+ return Object.fromEntries(
133
+ Object.entries(transformers).map(([key, transformer]) => [key, (name) => transformer(name, helpers)])
134
+ );
135
+ }
136
+ var DEFAULT_NAME_TRANSFORMERS = {
137
+ accountDecodeFunction: (name) => `decode${pascalCase(name)}`,
138
+ accountFetchAllFunction: (name) => `fetchAll${pascalCase(name)}`,
139
+ accountFetchAllMaybeFunction: (name) => `fetchAllMaybe${pascalCase(name)}`,
140
+ accountFetchFromSeedsFunction: (name) => `fetch${pascalCase(name)}FromSeeds`,
141
+ accountFetchFunction: (name) => `fetch${pascalCase(name)}`,
142
+ accountFetchMaybeFromSeedsFunction: (name) => `fetchMaybe${pascalCase(name)}FromSeeds`,
143
+ accountFetchMaybeFunction: (name) => `fetchMaybe${pascalCase(name)}`,
144
+ accountGetSizeFunction: (name) => `get${pascalCase(name)}Size`,
145
+ codecFunction: (name) => `get${pascalCase(name)}Codec`,
146
+ constant: (name) => snakeCase(name).toUpperCase(),
147
+ constantFunction: (name) => `get${pascalCase(name)}Bytes`,
148
+ dataArgsType: (name) => `${pascalCase(name)}Args`,
149
+ dataType: (name) => `${pascalCase(name)}`,
150
+ decoderFunction: (name) => `get${pascalCase(name)}Decoder`,
151
+ discriminatedUnionDiscriminator: () => "__kind",
152
+ discriminatedUnionFunction: (name) => `${camelCase(name)}`,
153
+ discriminatedUnionVariant: (name) => `${pascalCase(name)}`,
154
+ encoderFunction: (name) => `get${pascalCase(name)}Encoder`,
155
+ enumVariant: (name) => `${pascalCase(name)}`,
156
+ instructionAsyncFunction: (name) => `get${pascalCase(name)}InstructionAsync`,
157
+ instructionAsyncInputType: (name) => `${pascalCase(name)}AsyncInput`,
158
+ instructionDataType: (name) => `${pascalCase(name)}InstructionData`,
159
+ instructionExtraType: (name) => `${pascalCase(name)}InstructionExtra`,
160
+ instructionParseFunction: (name) => `parse${pascalCase(name)}Instruction`,
161
+ instructionParsedType: (name) => `Parsed${pascalCase(name)}Instruction`,
162
+ instructionSyncFunction: (name) => `get${pascalCase(name)}Instruction`,
163
+ instructionSyncInputType: (name) => `${pascalCase(name)}Input`,
164
+ instructionType: (name) => `${pascalCase(name)}Instruction`,
165
+ isDiscriminatedUnionFunction: (name) => `is${pascalCase(name)}`,
166
+ pdaFindFunction: (name) => `find${pascalCase(name)}Pda`,
167
+ pdaSeedsType: (name) => `${pascalCase(name)}Seeds`,
168
+ programAccountsEnum: (name) => `${pascalCase(name)}Account`,
169
+ programAccountsEnumVariant: (name) => `${pascalCase(name)}`,
170
+ programAccountsIdentifierFunction: (name) => `identify${pascalCase(name)}Account`,
171
+ programAddressConstant: (name) => `${snakeCase(name).toUpperCase()}_PROGRAM_ADDRESS`,
172
+ programErrorConstant: (name) => snakeCase(name).toUpperCase(),
173
+ programErrorConstantPrefix: (name) => `${snakeCase(name).toUpperCase()}_ERROR__`,
174
+ programErrorMessagesMap: (name) => `${camelCase(name)}ErrorMessages`,
175
+ programErrorUnion: (name) => `${pascalCase(name)}Error`,
176
+ programGetErrorMessageFunction: (name) => `get${pascalCase(name)}ErrorMessage`,
177
+ programInstructionsEnum: (name) => `${pascalCase(name)}Instruction`,
178
+ programInstructionsEnumVariant: (name) => `${pascalCase(name)}`,
179
+ programInstructionsIdentifierFunction: (name) => `identify${pascalCase(name)}Instruction`,
180
+ programInstructionsParsedUnionType: (name) => `Parsed${pascalCase(name)}Instruction`,
181
+ programIsErrorFunction: (name) => `is${pascalCase(name)}Error`,
182
+ resolverFunction: (name) => `${camelCase(name)}`
132
183
  };
133
184
 
185
+ // src/utils/fragment.ts
186
+ import { createFragmentTemplate } from "@codama/renderers-core";
187
+ function createFragment(content) {
188
+ return Object.freeze({ content, features: /* @__PURE__ */ new Set(), imports: createImportMap() });
189
+ }
190
+ function isFragment(value) {
191
+ return typeof value === "object" && value !== null && "content" in value;
192
+ }
193
+ function fragment(template, ...items) {
194
+ return createFragmentTemplate(template, items, isFragment, mergeFragments);
195
+ }
196
+ function mergeFragments(fragments, mergeContent) {
197
+ const filteredFragments = fragments.filter((f) => f !== void 0);
198
+ return Object.freeze({
199
+ content: mergeContent(filteredFragments.map((fragment2) => fragment2.content)),
200
+ features: new Set(filteredFragments.flatMap((f) => [...f.features])),
201
+ imports: mergeImportMaps(filteredFragments.map((f) => f.imports))
202
+ });
203
+ }
204
+ function use(importInput, module) {
205
+ const importInfo = parseImportInput(importInput);
206
+ return addFragmentImports(createFragment(importInfo.usedIdentifier), module, [importInput]);
207
+ }
208
+ function mergeFragmentImports(fragment2, importMaps) {
209
+ return Object.freeze({ ...fragment2, imports: mergeImportMaps([fragment2.imports, ...importMaps]) });
210
+ }
211
+ function addFragmentImports(fragment2, module, importInputs) {
212
+ return Object.freeze({ ...fragment2, imports: addToImportMap(fragment2.imports, module, importInputs) });
213
+ }
214
+ function removeFragmentImports(fragment2, module, usedIdentifiers) {
215
+ return Object.freeze({ ...fragment2, imports: removeFromImportMap(fragment2.imports, module, usedIdentifiers) });
216
+ }
217
+ function addFragmentFeatures(fragment2, features) {
218
+ return Object.freeze({ ...fragment2, features: /* @__PURE__ */ new Set([...fragment2.features, ...features]) });
219
+ }
220
+ function getExportAllFragment(module) {
221
+ return fragment`export * from '${module}';`;
222
+ }
223
+ function getDocblockFragment(lines, withLineJump = false) {
224
+ const lineJump = withLineJump ? "\n" : "";
225
+ if (lines.length === 0) return;
226
+ if (lines.length === 1) return fragment`/** ${lines[0]} */${lineJump}`;
227
+ const prefixedLines = lines.map((line) => line ? ` * ${line}` : " *");
228
+ return fragment`/**\n${prefixedLines.join("\n")}\n */${lineJump}`;
229
+ }
230
+ function getPageFragment(page, scope) {
231
+ const header = getDocblockFragment([
232
+ "This code was AUTOGENERATED using the Codama library.",
233
+ "Please DO NOT EDIT THIS FILE, instead use visitors",
234
+ "to add features, then rerun Codama to update it.",
235
+ "",
236
+ "@see https://github.com/codama-idl/codama"
237
+ ]);
238
+ const imports = page.imports.size === 0 ? void 0 : fragment`${importMapToString(page.imports, scope.dependencyMap, scope.useGranularImports)}`;
239
+ return mergeFragments([header, imports, page], (cs) => cs.join("\n\n"));
240
+ }
241
+
242
+ // src/utils/typeManifest.ts
243
+ function typeManifest(input = {}) {
244
+ return Object.freeze({
245
+ decoder: fragment``,
246
+ encoder: fragment``,
247
+ isEnum: false,
248
+ looseType: fragment``,
249
+ strictType: fragment``,
250
+ value: fragment``,
251
+ ...input
252
+ });
253
+ }
254
+ function mergeTypeManifests(manifests, options = {}) {
255
+ const { mergeTypes, mergeCodecs, mergeValues } = options;
256
+ const merge = (fragmentFn, mergeFn) => mergeFn ? mergeFragments(manifests.map(fragmentFn), mergeFn) : fragment``;
257
+ return Object.freeze({
258
+ decoder: merge((m) => m.decoder, mergeCodecs),
259
+ encoder: merge((m) => m.encoder, mergeCodecs),
260
+ isEnum: false,
261
+ looseType: merge((m) => m.looseType, mergeTypes),
262
+ strictType: merge((m) => m.strictType, mergeTypes),
263
+ value: merge((m) => m.value, mergeValues)
264
+ });
265
+ }
266
+
267
+ // src/visitors/getRenderMapVisitor.ts
268
+ import {
269
+ camelCase as camelCase14,
270
+ getAllAccounts,
271
+ getAllDefinedTypes,
272
+ getAllInstructionsWithSubs as getAllInstructionsWithSubs2,
273
+ getAllPdas,
274
+ getAllPrograms
275
+ } from "@codama/nodes";
276
+ import { createRenderMap, mergeRenderMaps } from "@codama/renderers-core";
277
+ import {
278
+ extendVisitor as extendVisitor2,
279
+ getByteSizeVisitor,
280
+ getResolvedInstructionInputsVisitor,
281
+ LinkableDictionary as LinkableDictionary3,
282
+ NodeStack as NodeStack2,
283
+ pipe as pipe16,
284
+ recordLinkablesOnFirstVisitVisitor,
285
+ recordNodeStackVisitor as recordNodeStackVisitor2,
286
+ staticVisitor as staticVisitor2,
287
+ visit as visit9
288
+ } from "@codama/visitors-core";
289
+
290
+ // src/fragments/accountFetchHelpers.ts
291
+ import { getLastNodeFromPath, pipe } from "@codama/visitors-core";
292
+
134
293
  // src/utils/async.ts
135
294
  import {
136
295
  accountValueNode,
@@ -226,7 +385,7 @@ function getBytesFromBytesValueNode(node) {
226
385
 
227
386
  // src/utils/customData.ts
228
387
  import {
229
- camelCase,
388
+ camelCase as camelCase2,
230
389
  definedTypeLinkNode,
231
390
  definedTypeNode,
232
391
  isNode as isNode2,
@@ -235,13 +394,13 @@ import {
235
394
  var parseCustomDataOptions = (customDataOptions, defaultSuffix) => new Map(
236
395
  customDataOptions.map((o) => {
237
396
  const options = typeof o === "string" ? { name: o } : o;
238
- const importAs = camelCase(options.importAs ?? `${options.name}${defaultSuffix}`);
397
+ const importAs = camelCase2(options.importAs ?? `${options.name}${defaultSuffix}`);
239
398
  const importFrom = options.importFrom ?? "hooked";
240
399
  return [
241
- camelCase(options.name),
400
+ camelCase2(options.name),
242
401
  {
243
402
  extract: options.extract ?? false,
244
- extractAs: options.extractAs ? camelCase(options.extractAs) : importAs,
403
+ extractAs: options.extractAs ? camelCase2(options.extractAs) : importAs,
245
404
  importAs,
246
405
  importFrom,
247
406
  linkNode: definedTypeLinkNode(importAs)
@@ -263,74 +422,6 @@ var getDefinedTypeNodesToExtract = (nodes, parsedCustomDataOptions) => nodes.fla
263
422
  ];
264
423
  });
265
424
 
266
- // src/utils/fragment.ts
267
- import { joinPath } from "@codama/renderers-core";
268
-
269
- // src/utils/render.ts
270
- import { dirname as pathDirname, join } from "path";
271
- import { fileURLToPath } from "url";
272
- import { camelCase as camelCase2, kebabCase, pascalCase, snakeCase, titleCase } from "@codama/nodes";
273
- import nunjucks from "nunjucks";
274
- function jsDocblock(docs) {
275
- if (docs.length <= 0) return "";
276
- if (docs.length === 1) return `/** ${docs[0]} */
277
- `;
278
- const lines = docs.map((doc) => ` * ${doc}`);
279
- return `/**
280
- ${lines.join("\n")}
281
- */
282
- `;
283
- }
284
- var render = (template, context, options) => {
285
- const dirname = true ? pathDirname(fileURLToPath(import.meta.url)) : __dirname;
286
- const templates = false ? join(dirname, "..", "..", "public", "templates") : join(dirname, "templates");
287
- const env = nunjucks.configure(templates, { autoescape: false, trimBlocks: true, ...options });
288
- env.addFilter("pascalCase", pascalCase);
289
- env.addFilter("camelCase", camelCase2);
290
- env.addFilter("snakeCase", snakeCase);
291
- env.addFilter("kebabCase", kebabCase);
292
- env.addFilter("titleCase", titleCase);
293
- env.addFilter("jsDocblock", jsDocblock);
294
- return env.render(template, context);
295
- };
296
-
297
- // src/utils/fragment.ts
298
- function fragment(content) {
299
- return Object.freeze({
300
- content,
301
- features: /* @__PURE__ */ new Set(),
302
- imports: new ImportMap()
303
- });
304
- }
305
- function fragmentFromTemplate(fragmentFile, context, options) {
306
- return fragment(render(joinPath("fragments", fragmentFile), context, options));
307
- }
308
- function mergeFragments(fragments, mergeContent) {
309
- return Object.freeze({
310
- content: mergeContent(fragments.map((fragment2) => fragment2.content)),
311
- features: new Set(fragments.flatMap((f) => [...f.features])),
312
- imports: new ImportMap().mergeWith(...fragments.map((f) => f.imports))
313
- });
314
- }
315
- function mergeFragmentImports(fragment2, importMaps) {
316
- return Object.freeze({
317
- ...fragment2,
318
- imports: new ImportMap().mergeWith(fragment2.imports, ...importMaps)
319
- });
320
- }
321
- function addFragmentImports(fragment2, module, imports) {
322
- return Object.freeze({
323
- ...fragment2,
324
- imports: new ImportMap().mergeWith(fragment2.imports).add(module, imports)
325
- });
326
- }
327
- function addFragmentFeatures(fragment2, features) {
328
- return Object.freeze({
329
- ...fragment2,
330
- features: /* @__PURE__ */ new Set([...fragment2.features, ...features])
331
- });
332
- }
333
-
334
425
  // src/utils/linkOverrides.ts
335
426
  import { CODAMA_ERROR__UNEXPECTED_NODE_KIND, CodamaError } from "@codama/errors";
336
427
  function getImportFromFactory(overrides, customAccountData, customInstructionData) {
@@ -380,79 +471,62 @@ function getImportFromFactory(overrides, customAccountData, customInstructionDat
380
471
  };
381
472
  }
382
473
 
383
- // src/TypeManifest.ts
384
- function typeManifest(input = {}) {
385
- return Object.freeze({
386
- decoder: fragment(""),
387
- encoder: fragment(""),
388
- isEnum: false,
389
- looseType: fragment(""),
390
- strictType: fragment(""),
391
- value: fragment(""),
392
- ...input
393
- });
394
- }
395
- function mergeTypeManifests(manifests, options = {}) {
396
- const { mergeTypes, mergeCodecs, mergeValues } = options;
397
- const merge = (fragmentFn, mergeFn) => mergeFn ? mergeFragments(manifests.map(fragmentFn), mergeFn) : fragment("");
398
- return Object.freeze({
399
- decoder: merge((m) => m.decoder, mergeCodecs),
400
- encoder: merge((m) => m.encoder, mergeCodecs),
401
- isEnum: false,
402
- looseType: merge((m) => m.looseType, mergeTypes),
403
- strictType: merge((m) => m.strictType, mergeTypes),
404
- value: merge((m) => m.value, mergeValues)
405
- });
406
- }
407
-
408
- // src/getRenderMapVisitor.ts
409
- import { join as join2 } from "path";
410
- import { logWarn } from "@codama/errors";
411
- import {
412
- camelCase as camelCase12,
413
- definedTypeNode as definedTypeNode2,
414
- getAllAccounts,
415
- getAllDefinedTypes,
416
- getAllInstructionsWithSubs as getAllInstructionsWithSubs2,
417
- getAllPdas,
418
- getAllPrograms,
419
- resolveNestedTypeNode as resolveNestedTypeNode4,
420
- structTypeNodeFromInstructionArgumentNodes as structTypeNodeFromInstructionArgumentNodes5
421
- } from "@codama/nodes";
422
- import { addToRenderMap, mergeRenderMaps, renderMap } from "@codama/renderers-core";
423
- import {
424
- extendVisitor as extendVisitor2,
425
- findProgramNodeFromPath as findProgramNodeFromPath7,
426
- getByteSizeVisitor,
427
- getResolvedInstructionInputsVisitor,
428
- LinkableDictionary as LinkableDictionary3,
429
- NodeStack as NodeStack2,
430
- pipe as pipe25,
431
- recordLinkablesOnFirstVisitVisitor,
432
- recordNodeStackVisitor as recordNodeStackVisitor2,
433
- staticVisitor as staticVisitor2,
434
- visit as visit6
435
- } from "@codama/visitors-core";
436
-
437
474
  // src/fragments/accountFetchHelpers.ts
438
- import { getLastNodeFromPath, pipe } from "@codama/visitors-core";
439
475
  function getAccountFetchHelpersFragment(scope) {
440
476
  const { accountPath, typeManifest: typeManifest2, nameApi, customAccountData } = scope;
441
477
  const accountNode = getLastNodeFromPath(accountPath);
478
+ const decodeFunction = nameApi.accountDecodeFunction(accountNode.name);
479
+ const fetchAllFunction = nameApi.accountFetchAllFunction(accountNode.name);
480
+ const fetchAllMaybeFunction = nameApi.accountFetchAllMaybeFunction(accountNode.name);
481
+ const fetchFunction = nameApi.accountFetchFunction(accountNode.name);
482
+ const fetchMaybeFunction = nameApi.accountFetchMaybeFunction(accountNode.name);
442
483
  const hasCustomData = customAccountData.has(accountNode.name);
443
- const accountTypeFragment = hasCustomData ? typeManifest2.strictType : fragment(nameApi.dataType(accountNode.name));
444
- const decoderFunctionFragment = hasCustomData ? typeManifest2.decoder : fragment(`${nameApi.decoderFunction(accountNode.name)}()`);
484
+ const accountType = hasCustomData ? typeManifest2.strictType : nameApi.dataType(accountNode.name);
485
+ const decoderFunction = hasCustomData ? typeManifest2.decoder : `${nameApi.decoderFunction(accountNode.name)}()`;
445
486
  return pipe(
446
- fragmentFromTemplate("accountFetchHelpers.njk", {
447
- accountType: accountTypeFragment.content,
448
- decodeFunction: nameApi.accountDecodeFunction(accountNode.name),
449
- decoderFunction: decoderFunctionFragment.content,
450
- fetchAllFunction: nameApi.accountFetchAllFunction(accountNode.name),
451
- fetchAllMaybeFunction: nameApi.accountFetchAllMaybeFunction(accountNode.name),
452
- fetchFunction: nameApi.accountFetchFunction(accountNode.name),
453
- fetchMaybeFunction: nameApi.accountFetchMaybeFunction(accountNode.name)
454
- }),
455
- (f) => mergeFragmentImports(f, [accountTypeFragment.imports, decoderFunctionFragment.imports]),
487
+ fragment`export function ${decodeFunction}<TAddress extends string = string>(encodedAccount: EncodedAccount<TAddress>): Account<${accountType}, TAddress>;
488
+ export function ${decodeFunction}<TAddress extends string = string>(encodedAccount: MaybeEncodedAccount<TAddress>): MaybeAccount<${accountType}, TAddress>;
489
+ export function ${decodeFunction}<TAddress extends string = string>(encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>): Account<${accountType}, TAddress> | MaybeAccount<${accountType}, TAddress> {
490
+ return decodeAccount(encodedAccount as MaybeEncodedAccount<TAddress>, ${decoderFunction});
491
+ }
492
+
493
+ export async function ${fetchFunction}<TAddress extends string = string>(
494
+ rpc: Parameters<typeof fetchEncodedAccount>[0],
495
+ address: Address<TAddress>,
496
+ config?: FetchAccountConfig,
497
+ ): Promise<Account<${accountType}, TAddress>> {
498
+ const maybeAccount = await ${fetchMaybeFunction}(rpc, address, config);
499
+ assertAccountExists(maybeAccount);
500
+ return maybeAccount;
501
+ }
502
+
503
+ export async function ${fetchMaybeFunction}<TAddress extends string = string>(
504
+ rpc: Parameters<typeof fetchEncodedAccount>[0],
505
+ address: Address<TAddress>,
506
+ config?: FetchAccountConfig,
507
+ ): Promise<MaybeAccount<${accountType}, TAddress>> {
508
+ const maybeAccount = await fetchEncodedAccount(rpc, address, config);
509
+ return ${decodeFunction}(maybeAccount);
510
+ }
511
+
512
+ export async function ${fetchAllFunction}(
513
+ rpc: Parameters<typeof fetchEncodedAccounts>[0],
514
+ addresses: Array<Address>,
515
+ config?: FetchAccountsConfig,
516
+ ): Promise<Account<${accountType}>[]> {
517
+ const maybeAccounts = await ${fetchAllMaybeFunction}(rpc, addresses, config);
518
+ assertAccountsExist(maybeAccounts);
519
+ return maybeAccounts;
520
+ }
521
+
522
+ export async function ${fetchAllMaybeFunction}(
523
+ rpc: Parameters<typeof fetchEncodedAccounts>[0],
524
+ addresses: Array<Address>,
525
+ config?: FetchAccountsConfig,
526
+ ): Promise<MaybeAccount<${accountType}>[]> {
527
+ const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
528
+ return maybeAccounts.map((maybeAccount) => ${decodeFunction}(maybeAccount));
529
+ }`,
456
530
  (f) => addFragmentImports(f, "solanaAddresses", ["type Address"]),
457
531
  (f) => addFragmentImports(f, "solanaAccounts", [
458
532
  "type Account",
@@ -470,35 +544,46 @@ function getAccountFetchHelpersFragment(scope) {
470
544
  );
471
545
  }
472
546
 
547
+ // src/fragments/accountPage.ts
548
+ import { resolveNestedTypeNode as resolveNestedTypeNode2 } from "@codama/nodes";
549
+ import { findProgramNodeFromPath, getLastNodeFromPath as getLastNodeFromPath5, visit as visit2 } from "@codama/visitors-core";
550
+
473
551
  // src/fragments/accountPdaHelpers.ts
474
552
  import { isNodeFilter } from "@codama/nodes";
475
- import { findProgramNodeFromPath, getLastNodeFromPath as getLastNodeFromPath2, pipe as pipe2 } from "@codama/visitors-core";
553
+ import { getLastNodeFromPath as getLastNodeFromPath2, pipe as pipe2 } from "@codama/visitors-core";
476
554
  function getAccountPdaHelpersFragment(scope) {
477
555
  const { accountPath, nameApi, linkables, customAccountData, typeManifest: typeManifest2 } = scope;
478
556
  const accountNode = getLastNodeFromPath2(accountPath);
479
- const programNode = findProgramNodeFromPath(accountPath);
480
557
  const pdaNode = accountNode.pda ? linkables.get([...accountPath, accountNode.pda]) : void 0;
481
- if (!pdaNode) {
482
- return fragment("");
483
- }
484
- const accountTypeFragment = customAccountData.has(accountNode.name) ? typeManifest2.strictType : fragment(nameApi.dataType(accountNode.name));
558
+ if (!pdaNode) return;
559
+ const accountType = customAccountData.has(accountNode.name) ? typeManifest2.strictType : nameApi.dataType(accountNode.name);
485
560
  const importFrom = "generatedPdas";
486
561
  const pdaSeedsType = nameApi.pdaSeedsType(pdaNode.name);
487
562
  const findPdaFunction = nameApi.pdaFindFunction(pdaNode.name);
488
563
  const hasVariableSeeds = pdaNode.seeds.filter(isNodeFilter("variablePdaSeedNode")).length > 0;
564
+ const fetchFromSeedsFunction = nameApi.accountFetchFromSeedsFunction(accountNode.name);
565
+ const fetchMaybeFromSeedsFunction = nameApi.accountFetchMaybeFromSeedsFunction(accountNode.name);
566
+ const fetchMaybeFunction = nameApi.accountFetchMaybeFunction(accountNode.name);
489
567
  return pipe2(
490
- fragmentFromTemplate("accountPdaHelpers.njk", {
491
- accountType: accountTypeFragment.content,
492
- fetchFromSeedsFunction: nameApi.accountFetchFromSeedsFunction(accountNode.name),
493
- fetchFunction: nameApi.accountFetchFunction(accountNode.name),
494
- fetchMaybeFromSeedsFunction: nameApi.accountFetchMaybeFromSeedsFunction(accountNode.name),
495
- fetchMaybeFunction: nameApi.accountFetchMaybeFunction(accountNode.name),
496
- findPdaFunction,
497
- hasVariableSeeds,
498
- pdaSeedsType,
499
- program: programNode
500
- }),
501
- (f) => mergeFragmentImports(f, [accountTypeFragment.imports]),
568
+ fragment`export async function ${fetchFromSeedsFunction}(
569
+ rpc: Parameters<typeof fetchEncodedAccount>[0],
570
+ ${hasVariableSeeds ? `seeds: ${pdaSeedsType},` : ""}
571
+ config: FetchAccountConfig & { programAddress?: Address } = {},
572
+ ): Promise<Account<${accountType}>> {
573
+ const maybeAccount = await ${fetchMaybeFromSeedsFunction}(rpc, ${hasVariableSeeds ? "seeds, " : ""}config);
574
+ assertAccountExists(maybeAccount);
575
+ return maybeAccount;
576
+ }
577
+
578
+ export async function ${fetchMaybeFromSeedsFunction}(
579
+ rpc: Parameters<typeof fetchEncodedAccount>[0],
580
+ ${hasVariableSeeds ? `seeds: ${pdaSeedsType},` : ""}
581
+ config: FetchAccountConfig & { programAddress?: Address } = {},
582
+ ): Promise<MaybeAccount<${accountType}>> {
583
+ const { programAddress, ...fetchConfig } = config;
584
+ const [address] = await ${findPdaFunction}(${hasVariableSeeds ? "seeds, " : ""}{ programAddress });
585
+ return await ${fetchMaybeFunction}(rpc, address, fetchConfig);
586
+ }`,
502
587
  (f) => addFragmentImports(f, importFrom, hasVariableSeeds ? [pdaSeedsType, findPdaFunction] : [findPdaFunction]),
503
588
  (f) => addFragmentImports(f, "solanaAddresses", ["type Address"]),
504
589
  (f) => addFragmentImports(f, "solanaAccounts", [
@@ -515,13 +600,11 @@ import { getLastNodeFromPath as getLastNodeFromPath3 } from "@codama/visitors-co
515
600
  function getAccountSizeHelpersFragment(scope) {
516
601
  const { accountPath, nameApi } = scope;
517
602
  const accountNode = getLastNodeFromPath3(accountPath);
518
- if (accountNode.size == null) {
519
- return fragment("");
520
- }
521
- return fragmentFromTemplate("accountSizeHelpers.njk", {
522
- account: accountNode,
523
- getSizeFunction: nameApi.accountGetSizeFunction(accountNode.name)
524
- });
603
+ if (accountNode.size == null) return;
604
+ const getSizeFunction = nameApi.accountGetSizeFunction(accountNode.name);
605
+ return fragment`export function ${getSizeFunction}(): number {
606
+ return ${accountNode.size};
607
+ }`;
525
608
  }
526
609
 
527
610
  // src/fragments/accountType.ts
@@ -529,88 +612,72 @@ import { resolveNestedTypeNode } from "@codama/nodes";
529
612
  import { getLastNodeFromPath as getLastNodeFromPath4 } from "@codama/visitors-core";
530
613
 
531
614
  // src/fragments/type.ts
532
- import { pipe as pipe3 } from "@codama/visitors-core";
533
615
  function getTypeFragment(scope) {
534
616
  const { name, manifest, nameApi, docs = [] } = scope;
535
- return pipe3(
536
- fragmentFromTemplate("type.njk", {
537
- docs,
538
- looseName: nameApi.dataArgsType(name),
539
- manifest,
540
- strictName: nameApi.dataType(name)
541
- }),
542
- (f) => !manifest.isEnum ? mergeFragmentImports(f, [manifest.strictType.imports, manifest.looseType.imports]) : f
543
- );
617
+ const docblock = getDocblockFragment(docs, true);
618
+ const strictName = nameApi.dataType(name);
619
+ const looseName = nameApi.dataArgsType(name);
620
+ const aliasedLooseName = `export type ${looseName} = ${strictName};`;
621
+ if (manifest.isEnum) {
622
+ return fragment`${docblock}export enum ${strictName} ${manifest.strictType};\n\n${aliasedLooseName}`;
623
+ }
624
+ const looseExport = manifest.strictType.content === manifest.looseType.content ? aliasedLooseName : fragment`export type ${looseName} = ${manifest.looseType};`;
625
+ return fragment`${docblock}export type ${strictName} = ${manifest.strictType};\n\n${looseExport}`;
544
626
  }
545
627
 
546
- // src/fragments/typeCodec.ts
547
- import { pipe as pipe6 } from "@codama/visitors-core";
548
-
549
628
  // src/fragments/typeDecoder.ts
550
629
  import { isDataEnum, isNode as isNode3 } from "@codama/nodes";
551
- import { pipe as pipe4 } from "@codama/visitors-core";
552
630
  function getTypeDecoderFragment(scope) {
553
631
  const { name, node, manifest, nameApi, docs = [] } = scope;
554
- const decoderType = typeof scope.size === "number" ? "FixedSizeDecoder" : "Decoder";
555
- const useTypeCast = isNode3(node, "enumTypeNode") && isDataEnum(node) && typeof scope.size === "number";
556
- return pipe4(
557
- fragmentFromTemplate("typeDecoder.njk", {
558
- decoderFunction: nameApi.decoderFunction(name),
559
- decoderType,
560
- docs,
561
- looseName: nameApi.dataArgsType(name),
562
- manifest,
563
- strictName: nameApi.dataType(name),
564
- useTypeCast
565
- }),
566
- (f) => mergeFragmentImports(f, [manifest.decoder.imports]),
567
- (f) => addFragmentImports(f, "solanaCodecsCore", [`type ${decoderType}`])
632
+ const decoderFunction = nameApi.decoderFunction(name);
633
+ const strictName = nameApi.dataType(name);
634
+ const docblock = getDocblockFragment(docs, true);
635
+ const decoderType = use(
636
+ typeof scope.size === "number" ? "type FixedSizeDecoder" : "type Decoder",
637
+ "solanaCodecsCore"
568
638
  );
639
+ const useTypeCast = isNode3(node, "enumTypeNode") && isDataEnum(node) && typeof scope.size === "number";
640
+ const typeCast = useTypeCast ? fragment` as ${decoderType}<${strictName}>` : "";
641
+ return fragment`${docblock}export function ${decoderFunction}(): ${decoderType}<${strictName}> {
642
+ return ${manifest.decoder}${typeCast};
643
+ }`;
569
644
  }
570
645
 
571
646
  // src/fragments/typeEncoder.ts
572
647
  import { isDataEnum as isDataEnum2, isNode as isNode4 } from "@codama/nodes";
573
- import { pipe as pipe5 } from "@codama/visitors-core";
574
648
  function getTypeEncoderFragment(scope) {
575
649
  const { name, node, manifest, nameApi, docs = [] } = scope;
576
- const encoderType = typeof scope.size === "number" ? "FixedSizeEncoder" : "Encoder";
577
- const useTypeCast = isNode4(node, "enumTypeNode") && isDataEnum2(node) && typeof scope.size === "number";
578
- return pipe5(
579
- fragmentFromTemplate("typeEncoder.njk", {
580
- docs,
581
- encoderFunction: nameApi.encoderFunction(name),
582
- encoderType,
583
- looseName: nameApi.dataArgsType(name),
584
- manifest,
585
- strictName: nameApi.dataType(name),
586
- useTypeCast
587
- }),
588
- (f) => mergeFragmentImports(f, [manifest.encoder.imports]),
589
- (f) => addFragmentImports(f, "solanaCodecsCore", [`type ${encoderType}`])
650
+ const encoderFunction = nameApi.encoderFunction(name);
651
+ const looseName = nameApi.dataArgsType(name);
652
+ const docblock = getDocblockFragment(docs, true);
653
+ const encoderType = use(
654
+ typeof scope.size === "number" ? "type FixedSizeEncoder" : "type Encoder",
655
+ "solanaCodecsCore"
590
656
  );
657
+ const useTypeCast = isNode4(node, "enumTypeNode") && isDataEnum2(node) && typeof scope.size === "number";
658
+ const typeCast = useTypeCast ? fragment` as ${encoderType}<${looseName}>` : "";
659
+ return fragment`${docblock}export function ${encoderFunction}(): ${encoderType}<${looseName}> {
660
+ return ${manifest.encoder}${typeCast};
661
+ }`;
591
662
  }
592
663
 
593
664
  // src/fragments/typeCodec.ts
594
665
  function getTypeCodecFragment(scope) {
595
- const { name, manifest, nameApi } = scope;
596
- const codecType = typeof scope.size === "number" ? "FixedSizeCodec" : "Codec";
666
+ const { codecDocs = [], name, nameApi } = scope;
667
+ const codecFunction = nameApi.codecFunction(name);
668
+ const decoderFunction = nameApi.decoderFunction(name);
669
+ const encoderFunction = nameApi.encoderFunction(name);
670
+ const looseName = nameApi.dataArgsType(name);
671
+ const strictName = nameApi.dataType(name);
672
+ const docblock = getDocblockFragment(codecDocs, true);
673
+ const codecType = use(typeof scope.size === "number" ? "type FixedSizeCodec" : "type Codec", "solanaCodecsCore");
597
674
  return mergeFragments(
598
675
  [
599
676
  getTypeEncoderFragment({ ...scope, docs: scope.encoderDocs }),
600
677
  getTypeDecoderFragment({ ...scope, docs: scope.decoderDocs }),
601
- pipe6(
602
- fragmentFromTemplate("typeCodec.njk", {
603
- codecFunction: nameApi.codecFunction(name),
604
- codecType,
605
- decoderFunction: nameApi.decoderFunction(name),
606
- docs: scope.codecDocs,
607
- encoderFunction: nameApi.encoderFunction(name),
608
- looseName: nameApi.dataArgsType(name),
609
- manifest,
610
- strictName: nameApi.dataType(name)
611
- }),
612
- (f) => addFragmentImports(f, "solanaCodecsCore", [`type ${codecType}`, "combineCodec"])
613
- )
678
+ fragment`${docblock}export function ${codecFunction}(): ${codecType}<${looseName}, ${strictName}> {
679
+ return ${use("combineCodec", "solanaCodecsCore")}(${encoderFunction}(), ${decoderFunction}());
680
+ }`
614
681
  ],
615
682
  (renders) => renders.join("\n\n")
616
683
  );
@@ -628,9 +695,7 @@ function getTypeWithCodecFragment(scope) {
628
695
  function getAccountTypeFragment(scope) {
629
696
  const { accountPath, typeManifest: typeManifest2, nameApi, customAccountData } = scope;
630
697
  const accountNode = getLastNodeFromPath4(accountPath);
631
- if (customAccountData.has(accountNode.name)) {
632
- return fragment("");
633
- }
698
+ if (customAccountData.has(accountNode.name)) return;
634
699
  return getTypeWithCodecFragment({
635
700
  manifest: typeManifest2,
636
701
  name: accountNode.name,
@@ -640,49 +705,119 @@ function getAccountTypeFragment(scope) {
640
705
  });
641
706
  }
642
707
 
708
+ // src/fragments/discriminatorConstants.ts
709
+ import {
710
+ camelCase as camelCase3,
711
+ isNode as isNode5,
712
+ isNodeFilter as isNodeFilter2,
713
+ VALUE_NODES
714
+ } from "@codama/nodes";
715
+ import { visit } from "@codama/visitors-core";
716
+ function getDiscriminatorConstantsFragment(scope) {
717
+ const fragments = scope.discriminatorNodes.map((node) => getDiscriminatorConstantFragment(node, scope)).filter(Boolean);
718
+ return mergeFragments(fragments, (c) => c.join("\n\n"));
719
+ }
720
+ function getDiscriminatorConstantFragment(discriminatorNode, scope) {
721
+ switch (discriminatorNode.kind) {
722
+ case "constantDiscriminatorNode":
723
+ return getConstantDiscriminatorConstantFragment(discriminatorNode, scope);
724
+ case "fieldDiscriminatorNode":
725
+ return getFieldDiscriminatorConstantFragment(discriminatorNode, scope);
726
+ default:
727
+ return null;
728
+ }
729
+ }
730
+ function getConstantDiscriminatorConstantFragment(discriminatorNode, scope) {
731
+ const { discriminatorNodes, typeManifestVisitor, prefix } = scope;
732
+ const index = discriminatorNodes.filter(isNodeFilter2("constantDiscriminatorNode")).indexOf(discriminatorNode);
733
+ const suffix = index <= 0 ? "" : `_${index + 1}`;
734
+ const name = camelCase3(`${prefix}_discriminator${suffix}`);
735
+ const encoder = visit(discriminatorNode.constant.type, typeManifestVisitor).encoder;
736
+ const value = visit(discriminatorNode.constant.value, typeManifestVisitor).value;
737
+ return getConstantFragment({ ...scope, encoder, name, value });
738
+ }
739
+ function getFieldDiscriminatorConstantFragment(discriminatorNode, scope) {
740
+ const { fields, prefix, typeManifestVisitor } = scope;
741
+ const field = fields.find((f) => f.name === discriminatorNode.name);
742
+ if (!field || !field.defaultValue || !isNode5(field.defaultValue, VALUE_NODES)) {
743
+ return null;
744
+ }
745
+ const name = camelCase3(`${prefix}_${discriminatorNode.name}`);
746
+ const encoder = visit(field.type, typeManifestVisitor).encoder;
747
+ const value = visit(field.defaultValue, typeManifestVisitor).value;
748
+ return getConstantFragment({ ...scope, encoder, name, value });
749
+ }
750
+ function getConstantFragment(scope) {
751
+ const { encoder, name, nameApi, value } = scope;
752
+ const constantName = nameApi.constant(name);
753
+ const constantFunction = nameApi.constantFunction(name);
754
+ return fragment`export const ${constantName} = ${value};\n\nexport function ${constantFunction}() { return ${encoder}.encode(${constantName}); }`;
755
+ }
756
+
757
+ // src/fragments/accountPage.ts
758
+ function getAccountPageFragment(scope) {
759
+ const node = getLastNodeFromPath5(scope.accountPath);
760
+ if (!findProgramNodeFromPath(scope.accountPath)) {
761
+ throw new Error("Account must be visited inside a program.");
762
+ }
763
+ const typeManifest2 = visit2(node, scope.typeManifestVisitor);
764
+ const fields = resolveNestedTypeNode2(node.data).fields;
765
+ return mergeFragments(
766
+ [
767
+ getDiscriminatorConstantsFragment({
768
+ ...scope,
769
+ discriminatorNodes: node.discriminators ?? [],
770
+ fields,
771
+ prefix: node.name
772
+ }),
773
+ getAccountTypeFragment({ ...scope, typeManifest: typeManifest2 }),
774
+ getAccountFetchHelpersFragment({ ...scope, typeManifest: typeManifest2 }),
775
+ getAccountSizeHelpersFragment(scope),
776
+ getAccountPdaHelpersFragment({ ...scope, typeManifest: typeManifest2 })
777
+ ],
778
+ (cs) => cs.join("\n\n")
779
+ );
780
+ }
781
+
643
782
  // src/fragments/discriminatorCondition.ts
644
783
  import {
645
784
  constantDiscriminatorNode,
646
785
  constantValueNode,
647
786
  constantValueNodeFromBytes,
648
- isNode as isNode5,
649
- isNodeFilter as isNodeFilter2
787
+ isNode as isNode6,
788
+ isNodeFilter as isNodeFilter3
650
789
  } from "@codama/nodes";
651
790
  import { mapFragmentContent } from "@codama/renderers-core";
652
- import { pipe as pipe7, visit } from "@codama/visitors-core";
791
+ import { pipe as pipe3, visit as visit3 } from "@codama/visitors-core";
653
792
  import { getBase64Decoder } from "@solana/codecs-strings";
654
793
  function getDiscriminatorConditionFragment(scope) {
655
- return pipe7(
794
+ return pipe3(
656
795
  mergeFragments(
657
796
  scope.discriminators.flatMap((discriminator) => {
658
- if (isNode5(discriminator, "sizeDiscriminatorNode")) {
797
+ if (isNode6(discriminator, "sizeDiscriminatorNode")) {
659
798
  return [getSizeConditionFragment(discriminator, scope)];
660
799
  }
661
- if (isNode5(discriminator, "constantDiscriminatorNode")) {
800
+ if (isNode6(discriminator, "constantDiscriminatorNode")) {
662
801
  return [getByteConditionFragment(discriminator, scope)];
663
802
  }
664
- if (isNode5(discriminator, "fieldDiscriminatorNode")) {
803
+ if (isNode6(discriminator, "fieldDiscriminatorNode")) {
665
804
  return [getFieldConditionFragment(discriminator, scope)];
666
805
  }
667
806
  return [];
668
807
  }),
669
808
  (c) => c.join(" && ")
670
809
  ),
671
- (f) => mapFragmentContent(f, (c) => `if (${c}) { ${scope.ifTrue}; }`)
810
+ (f) => mapFragmentContent(f, (c) => `if (${c}) { ${scope.ifTrue} }`)
672
811
  );
673
812
  }
674
813
  function getSizeConditionFragment(discriminator, scope) {
675
814
  const { dataName } = scope;
676
- return fragment(`${dataName}.length === ${discriminator.size}`);
815
+ return fragment`${dataName}.length === ${discriminator.size}`;
677
816
  }
678
817
  function getByteConditionFragment(discriminator, scope) {
679
818
  const { dataName, typeManifestVisitor } = scope;
680
- const constant = visit(discriminator.constant, typeManifestVisitor).value;
681
- return pipe7(
682
- constant,
683
- (f) => mapFragmentContent(f, (c) => `containsBytes(${dataName}, ${c}, ${discriminator.offset})`),
684
- (f) => addFragmentImports(f, "solanaCodecsCore", ["containsBytes"])
685
- );
819
+ const constant = visit3(discriminator.constant, typeManifestVisitor).value;
820
+ return fragment`${use("containsBytes", "solanaCodecsCore")}(${dataName}, ${constant}, ${discriminator.offset})`;
686
821
  }
687
822
  function getFieldConditionFragment(discriminator, scope) {
688
823
  const field = scope.struct.fields.find((f) => f.name === discriminator.name);
@@ -691,7 +826,7 @@ function getFieldConditionFragment(discriminator, scope) {
691
826
  `Field discriminator "${discriminator.name}" does not have a matching argument with default value.`
692
827
  );
693
828
  }
694
- if (isNode5(field.type, "arrayTypeNode") && isNode5(field.type.item, "numberTypeNode") && field.type.item.format === "u8" && isNode5(field.type.count, "fixedCountNode") && isNode5(field.defaultValue, "arrayValueNode") && field.defaultValue.items.every(isNodeFilter2("numberValueNode"))) {
829
+ if (isNode6(field.type, "arrayTypeNode") && isNode6(field.type.item, "numberTypeNode") && field.type.item.format === "u8" && isNode6(field.type.count, "fixedCountNode") && isNode6(field.defaultValue, "arrayValueNode") && field.defaultValue.items.every(isNodeFilter3("numberValueNode"))) {
695
830
  const base64Bytes = getBase64Decoder().decode(
696
831
  new Uint8Array(field.defaultValue.items.map((node) => node.number))
697
832
  );
@@ -706,35 +841,103 @@ function getFieldConditionFragment(discriminator, scope) {
706
841
  );
707
842
  }
708
843
 
844
+ // src/fragments/errorPage.ts
845
+ function getErrorPageFragment(scope) {
846
+ return mergeFragments(
847
+ [
848
+ getConstantsFragment(scope),
849
+ getConstantUnionTypeFragment(scope),
850
+ getErrorMessagesFragment(scope),
851
+ getErrorMessageFunctionFragment(scope),
852
+ getIsErrorFunctionFragment(scope)
853
+ ],
854
+ (cs) => cs.join("\n\n")
855
+ );
856
+ }
857
+ function getConstantsFragment(scope) {
858
+ const constantPrefix = scope.nameApi.programErrorConstantPrefix(scope.programNode.name);
859
+ return mergeFragments(
860
+ [...scope.programNode.errors].sort((a, b) => a.code - b.code).map((error) => {
861
+ const docs = getDocblockFragment(error.docs ?? [], true);
862
+ const name = constantPrefix + scope.nameApi.programErrorConstant(error.name);
863
+ return fragment`${docs}export const ${name} = 0x${error.code.toString(16)}; // ${error.code}`;
864
+ }),
865
+ (cs) => cs.join("\n")
866
+ );
867
+ }
868
+ function getConstantUnionTypeFragment(scope) {
869
+ const constantPrefix = scope.nameApi.programErrorConstantPrefix(scope.programNode.name);
870
+ const typeName = scope.nameApi.programErrorUnion(scope.programNode.name);
871
+ const errorTypes = mergeFragments(
872
+ [...scope.programNode.errors].sort((a, b) => a.name.localeCompare(b.name)).map((error) => fragment`typeof ${constantPrefix + scope.nameApi.programErrorConstant(error.name)}`),
873
+ (cs) => cs.join(" | ")
874
+ );
875
+ return fragment`export type ${typeName} = ${errorTypes};`;
876
+ }
877
+ function getErrorMessagesFragment(scope) {
878
+ const mapName = scope.nameApi.programErrorMessagesMap(scope.programNode.name);
879
+ const errorUnionType = scope.nameApi.programErrorUnion(scope.programNode.name);
880
+ const constantPrefix = scope.nameApi.programErrorConstantPrefix(scope.programNode.name);
881
+ const messageEntries = mergeFragments(
882
+ [...scope.programNode.errors].sort((a, b) => a.name.localeCompare(b.name)).map((error) => {
883
+ const constantName = constantPrefix + scope.nameApi.programErrorConstant(error.name);
884
+ const escapedMessage = error.message.replace(/`/g, "\\`");
885
+ return fragment`[${constantName}]: \`${escapedMessage}\``;
886
+ }),
887
+ (cs) => cs.join(", ")
888
+ );
889
+ return fragment`let ${mapName}: Record<${errorUnionType}, string> | undefined;
890
+ if (process.env.NODE_ENV !== 'production') {
891
+ ${mapName} = { ${messageEntries} };
892
+ }`;
893
+ }
894
+ function getErrorMessageFunctionFragment(scope) {
895
+ const functionName = scope.nameApi.programGetErrorMessageFunction(scope.programNode.name);
896
+ const errorUnionType = scope.nameApi.programErrorUnion(scope.programNode.name);
897
+ const messageMapName = scope.nameApi.programErrorMessagesMap(scope.programNode.name);
898
+ return fragment`export function ${functionName}(code: ${errorUnionType}): string {
899
+ if (process.env.NODE_ENV !== 'production') {
900
+ return (${messageMapName} as Record<${errorUnionType}, string>)[code];
901
+ }
902
+
903
+ return 'Error message not available in production bundles.';
904
+ }`;
905
+ }
906
+ function getIsErrorFunctionFragment(scope) {
907
+ const { programNode, nameApi } = scope;
908
+ const programAddressConstant = use(nameApi.programAddressConstant(programNode.name), "generatedPrograms");
909
+ const functionName = nameApi.programIsErrorFunction(programNode.name);
910
+ const programErrorUnion = nameApi.programErrorUnion(programNode.name);
911
+ return fragment`export function ${functionName}<TProgramErrorCode extends ${programErrorUnion}>(
912
+ error: unknown,
913
+ transactionMessage: { instructions: Record<number, { programAddress: ${use("type Address", "solanaAddresses")} }> },
914
+ code?: TProgramErrorCode,
915
+ ): error is ${use("type SolanaError", "solanaErrors")}<typeof ${use("type SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM", "solanaErrors")}> & Readonly<{ context: Readonly<{ code: TProgramErrorCode }> }> {
916
+ return ${use("isProgramError", "solanaPrograms")}<TProgramErrorCode>(error, transactionMessage, ${programAddressConstant}, code);
917
+ }`;
918
+ }
919
+
920
+ // src/fragments/indexPage.ts
921
+ function getIndexPageFragment(items) {
922
+ if (items.length === 0) return;
923
+ const names = items.map((item) => item.name).sort((a, b) => a.localeCompare(b)).map((name) => getExportAllFragment(`./${name}`));
924
+ return mergeFragments(names, (cs) => cs.join("\n"));
925
+ }
926
+
709
927
  // src/fragments/instructionAccountMeta.ts
710
928
  import { pascalCase as pascalCase2 } from "@codama/nodes";
711
- import { pipe as pipe8 } from "@codama/visitors-core";
712
929
  function getInstructionAccountMetaFragment(instructionAccountNode) {
713
930
  const typeParam = `TAccount${pascalCase2(instructionAccountNode.name)}`;
714
931
  if (instructionAccountNode.isSigner === true && instructionAccountNode.isWritable) {
715
- return pipe8(
716
- fragment(`WritableSignerAccount<${typeParam}> & AccountSignerMeta<${typeParam}>`),
717
- (f) => addFragmentImports(f, "solanaInstructions", ["type WritableSignerAccount"]),
718
- (f) => addFragmentImports(f, "solanaSigners", ["type AccountSignerMeta"])
719
- );
932
+ return fragment`${use("type WritableSignerAccount", "solanaInstructions")}<${typeParam}> & ${use("type AccountSignerMeta", "solanaSigners")}<${typeParam}>`;
720
933
  }
721
934
  if (instructionAccountNode.isSigner === true) {
722
- return pipe8(
723
- fragment(`ReadonlySignerAccount<${typeParam}> & AccountSignerMeta<${typeParam}>`),
724
- (f) => addFragmentImports(f, "solanaInstructions", ["type ReadonlySignerAccount"]),
725
- (f) => addFragmentImports(f, "solanaSigners", ["type AccountSignerMeta"])
726
- );
935
+ return fragment`${use("type ReadonlySignerAccount", "solanaInstructions")}<${typeParam}> & ${use("type AccountSignerMeta", "solanaSigners")}<${typeParam}>`;
727
936
  }
728
937
  if (instructionAccountNode.isWritable) {
729
- return pipe8(
730
- fragment(`WritableAccount<${typeParam}>`),
731
- (f) => addFragmentImports(f, "solanaInstructions", ["type WritableAccount"])
732
- );
938
+ return fragment`${use("type WritableAccount", "solanaInstructions")}<${typeParam}>`;
733
939
  }
734
- return pipe8(
735
- fragment(`ReadonlyAccount<${typeParam}>`),
736
- (f) => addFragmentImports(f, "solanaInstructions", ["type ReadonlyAccount"])
737
- );
940
+ return fragment`${use("type ReadonlyAccount", "solanaInstructions")}<${typeParam}>`;
738
941
  }
739
942
 
740
943
  // src/fragments/instructionAccountTypeParam.ts
@@ -742,31 +945,20 @@ import { pascalCase as pascalCase3 } from "@codama/nodes";
742
945
  import {
743
946
  findInstructionNodeFromPath,
744
947
  findProgramNodeFromPath as findProgramNodeFromPath2,
745
- getLastNodeFromPath as getLastNodeFromPath5,
746
- pipe as pipe9
948
+ getLastNodeFromPath as getLastNodeFromPath6
747
949
  } from "@codama/visitors-core";
748
950
  function getInstructionAccountTypeParamFragment(scope) {
749
951
  const { instructionAccountPath, allowAccountMeta, linkables } = scope;
750
- const instructionAccountNode = getLastNodeFromPath5(instructionAccountPath);
952
+ const instructionAccountNode = getLastNodeFromPath6(instructionAccountPath);
751
953
  const instructionNode = findInstructionNodeFromPath(instructionAccountPath);
752
954
  const programNode = findProgramNodeFromPath2(instructionAccountPath);
753
955
  const typeParam = `TAccount${pascalCase3(instructionAccountNode.name)}`;
754
- const accountMeta = allowAccountMeta ? " | AccountMeta<string>" : "";
755
- const imports = new ImportMap();
756
- if (allowAccountMeta) {
757
- imports.add("solanaInstructions", "type AccountMeta");
758
- }
956
+ const accountMeta = allowAccountMeta ? fragment` | ${use("type AccountMeta", "solanaInstructions")}<string>` : void 0;
759
957
  if (instructionNode.optionalAccountStrategy === "omitted" && instructionAccountNode.isOptional) {
760
- return pipe9(
761
- fragment(`${typeParam} extends string${accountMeta} | undefined = undefined`),
762
- (f) => mergeFragmentImports(f, [imports])
763
- );
958
+ return fragment`${typeParam} extends string${accountMeta} | undefined = undefined`;
764
959
  }
765
960
  const defaultAddress = getDefaultAddress(instructionAccountNode.defaultValue, programNode.publicKey, linkables);
766
- return pipe9(
767
- fragment(`${typeParam} extends string${accountMeta} = ${defaultAddress}`),
768
- (f) => mergeFragmentImports(f, [imports])
769
- );
961
+ return fragment`${typeParam} extends string${accountMeta} = ${defaultAddress}`;
770
962
  }
771
963
  function getDefaultAddress(defaultValue, programId, linkables) {
772
964
  switch (defaultValue?.kind) {
@@ -783,13 +975,13 @@ function getDefaultAddress(defaultValue, programId, linkables) {
783
975
  }
784
976
 
785
977
  // src/fragments/instructionByteDelta.ts
786
- import { assertIsNode, camelCase as camelCase3, isNode as isNode6 } from "@codama/nodes";
978
+ import { assertIsNode, camelCase as camelCase4, isNode as isNode7 } from "@codama/nodes";
787
979
  import { mapFragmentContent as mapFragmentContent2 } from "@codama/renderers-core";
788
- import { getLastNodeFromPath as getLastNodeFromPath6, pipe as pipe10 } from "@codama/visitors-core";
980
+ import { getLastNodeFromPath as getLastNodeFromPath7, pipe as pipe4 } from "@codama/visitors-core";
789
981
  function getInstructionByteDeltaFragment(scope) {
790
- const { byteDeltas } = getLastNodeFromPath6(scope.instructionPath);
982
+ const { byteDeltas } = getLastNodeFromPath7(scope.instructionPath);
791
983
  const fragments = (byteDeltas ?? []).flatMap((c) => getByteDeltaFragment(c, scope));
792
- if (fragments.length === 0) return fragment("");
984
+ if (fragments.length === 0) return;
793
985
  return mergeFragments(
794
986
  fragments,
795
987
  (c) => `// Bytes created or reallocated by the instruction.
@@ -798,71 +990,68 @@ const byteDelta: number = [${c.join(",")}].reduce((a, b) => a + b, 0);`
798
990
  }
799
991
  function getByteDeltaFragment(byteDelta, scope) {
800
992
  let bytesFragment = (() => {
801
- if (isNode6(byteDelta.value, "numberValueNode")) {
993
+ if (isNode7(byteDelta.value, "numberValueNode")) {
802
994
  return getNumberValueNodeFragment(byteDelta);
803
995
  }
804
- if (isNode6(byteDelta.value, "argumentValueNode")) {
996
+ if (isNode7(byteDelta.value, "argumentValueNode")) {
805
997
  return getArgumentValueNodeFragment(byteDelta);
806
998
  }
807
- if (isNode6(byteDelta.value, "accountLinkNode")) {
999
+ if (isNode7(byteDelta.value, "accountLinkNode")) {
808
1000
  return getAccountLinkNodeFragment(byteDelta, scope);
809
1001
  }
810
- if (isNode6(byteDelta.value, "resolverValueNode")) {
1002
+ if (isNode7(byteDelta.value, "resolverValueNode")) {
811
1003
  return getResolverValueNodeFragment(byteDelta, scope);
812
1004
  }
813
1005
  return null;
814
1006
  })();
815
1007
  if (bytesFragment === null) return [];
816
1008
  if (byteDelta.withHeader) {
817
- bytesFragment = pipe10(
818
- bytesFragment,
819
- (f) => mapFragmentContent2(f, (c) => `${c} + BASE_ACCOUNT_SIZE`),
820
- (f) => addFragmentImports(f, "solanaAccounts", ["BASE_ACCOUNT_SIZE"])
821
- );
1009
+ bytesFragment = fragment`${bytesFragment} + ${use("BASE_ACCOUNT_SIZE", "solanaAccounts")}`;
822
1010
  }
823
1011
  if (byteDelta.subtract) {
824
- bytesFragment = pipe10(bytesFragment, (f) => mapFragmentContent2(f, (c) => `- (${c})`));
1012
+ bytesFragment = pipe4(bytesFragment, (f) => mapFragmentContent2(f, (c) => `- (${c})`));
825
1013
  }
826
1014
  return [bytesFragment];
827
1015
  }
828
1016
  function getNumberValueNodeFragment(byteDelta) {
829
1017
  assertIsNode(byteDelta.value, "numberValueNode");
830
- return fragment(byteDelta.value.number.toString());
1018
+ return fragment`${byteDelta.value.number}`;
831
1019
  }
832
1020
  function getArgumentValueNodeFragment(byteDelta) {
833
1021
  assertIsNode(byteDelta.value, "argumentValueNode");
834
- const argumentName = camelCase3(byteDelta.value.name);
835
- return fragment(`Number(args.${argumentName})`);
1022
+ const argumentName = camelCase4(byteDelta.value.name);
1023
+ return fragment`Number(args.${argumentName})`;
836
1024
  }
837
1025
  function getAccountLinkNodeFragment(byteDelta, scope) {
838
1026
  assertIsNode(byteDelta.value, "accountLinkNode");
839
- const functionName = scope.nameApi.accountGetSizeFunction(byteDelta.value.name);
840
- const module = scope.getImportFrom(byteDelta.value);
841
- return pipe10(fragment(`${functionName}()`), (f) => addFragmentImports(f, module, [functionName]));
1027
+ const functionName = use(
1028
+ scope.nameApi.accountGetSizeFunction(byteDelta.value.name),
1029
+ scope.getImportFrom(byteDelta.value)
1030
+ );
1031
+ return fragment`${functionName}()`;
842
1032
  }
843
1033
  function getResolverValueNodeFragment(byteDelta, scope) {
844
1034
  assertIsNode(byteDelta.value, "resolverValueNode");
845
1035
  const isAsync = scope.asyncResolvers.includes(byteDelta.value.name);
846
1036
  if (!scope.useAsync && isAsync) return null;
847
1037
  const awaitKeyword = scope.useAsync && isAsync ? "await " : "";
848
- const functionName = scope.nameApi.resolverFunction(byteDelta.value.name);
849
- const module = scope.getImportFrom(byteDelta.value);
850
- return pipe10(
851
- fragment(`${awaitKeyword}${functionName}(resolverScope)`),
852
- (f) => addFragmentImports(f, module, [functionName]),
1038
+ const functionName = use(
1039
+ scope.nameApi.resolverFunction(byteDelta.value.name),
1040
+ scope.getImportFrom(byteDelta.value)
1041
+ );
1042
+ return pipe4(
1043
+ fragment`${awaitKeyword}${functionName}(resolverScope)`,
853
1044
  (f) => addFragmentFeatures(f, ["instruction:resolverScopeVariable"])
854
1045
  );
855
1046
  }
856
1047
 
857
1048
  // src/fragments/instructionData.ts
858
1049
  import { structTypeNodeFromInstructionArgumentNodes as structTypeNodeFromInstructionArgumentNodes2 } from "@codama/nodes";
859
- import { getLastNodeFromPath as getLastNodeFromPath7 } from "@codama/visitors-core";
1050
+ import { getLastNodeFromPath as getLastNodeFromPath8 } from "@codama/visitors-core";
860
1051
  function getInstructionDataFragment(scope) {
861
1052
  const { instructionPath, dataArgsManifest, nameApi, customInstructionData } = scope;
862
- const instructionNode = getLastNodeFromPath7(instructionPath);
863
- if (instructionNode.arguments.length === 0 || customInstructionData.has(instructionNode.name)) {
864
- return fragment("");
865
- }
1053
+ const instructionNode = getLastNodeFromPath8(instructionPath);
1054
+ if (instructionNode.arguments.length === 0 || customInstructionData.has(instructionNode.name)) return;
866
1055
  const instructionDataName = nameApi.instructionDataType(instructionNode.name);
867
1056
  return getTypeWithCodecFragment({
868
1057
  manifest: dataArgsManifest,
@@ -873,82 +1062,16 @@ function getInstructionDataFragment(scope) {
873
1062
  });
874
1063
  }
875
1064
 
876
- // src/fragments/discriminatorConstants.ts
877
- import {
878
- camelCase as camelCase4,
879
- isNode as isNode7,
880
- isNodeFilter as isNodeFilter3,
881
- VALUE_NODES
882
- } from "@codama/nodes";
883
- import { mapFragmentContent as mapFragmentContent3 } from "@codama/renderers-core";
884
- import { visit as visit2 } from "@codama/visitors-core";
885
- function getDiscriminatorConstantsFragment(scope) {
886
- const fragments = scope.discriminatorNodes.map((node) => getDiscriminatorConstantFragment(node, scope)).filter(Boolean);
887
- return mergeFragments(fragments, (c) => c.join("\n\n"));
888
- }
889
- function getDiscriminatorConstantFragment(discriminatorNode, scope) {
890
- switch (discriminatorNode.kind) {
891
- case "constantDiscriminatorNode":
892
- return getConstantDiscriminatorConstantFragment(discriminatorNode, scope);
893
- case "fieldDiscriminatorNode":
894
- return getFieldDiscriminatorConstantFragment(discriminatorNode, scope);
895
- default:
896
- return null;
897
- }
898
- }
899
- function getConstantDiscriminatorConstantFragment(discriminatorNode, scope) {
900
- const { discriminatorNodes, typeManifestVisitor, prefix } = scope;
901
- const index = discriminatorNodes.filter(isNodeFilter3("constantDiscriminatorNode")).indexOf(discriminatorNode);
902
- const suffix = index <= 0 ? "" : `_${index + 1}`;
903
- const name = camelCase4(`${prefix}_discriminator${suffix}`);
904
- const encoder = visit2(discriminatorNode.constant.type, typeManifestVisitor).encoder;
905
- const value = visit2(discriminatorNode.constant.value, typeManifestVisitor).value;
906
- return getConstantFragment({ ...scope, encoder, name, value });
907
- }
908
- function getFieldDiscriminatorConstantFragment(discriminatorNode, scope) {
909
- const { fields, prefix, typeManifestVisitor } = scope;
910
- const field = fields.find((f) => f.name === discriminatorNode.name);
911
- if (!field || !field.defaultValue || !isNode7(field.defaultValue, VALUE_NODES)) {
912
- return null;
913
- }
914
- const name = camelCase4(`${prefix}_${discriminatorNode.name}`);
915
- const encoder = visit2(field.type, typeManifestVisitor).encoder;
916
- const value = visit2(field.defaultValue, typeManifestVisitor).value;
917
- return getConstantFragment({ ...scope, encoder, name, value });
918
- }
919
- function getConstantFragment(scope) {
920
- const { encoder, name, nameApi, value } = scope;
921
- const constantName = nameApi.constant(name);
922
- const constantFunction = nameApi.constantFunction(name);
923
- return mergeFragments(
924
- [
925
- mapFragmentContent3(value, (c) => `export const ${constantName} = ${c};`),
926
- mapFragmentContent3(
927
- encoder,
928
- (c) => `export function ${constantFunction}() { return ${c}.encode(${constantName}); }`
929
- )
930
- ],
931
- (c) => c.join("\n\n")
932
- );
933
- }
934
-
935
1065
  // src/fragments/instructionExtraArgs.ts
936
- import { getLastNodeFromPath as getLastNodeFromPath8, pipe as pipe11 } from "@codama/visitors-core";
1066
+ import { mapFragmentContent as mapFragmentContent3 } from "@codama/renderers-core";
1067
+ import { getLastNodeFromPath as getLastNodeFromPath9 } from "@codama/visitors-core";
937
1068
  function getInstructionExtraArgsFragment(scope) {
938
1069
  const { instructionPath, extraArgsManifest, nameApi } = scope;
939
- const instructionNode = getLastNodeFromPath8(instructionPath);
940
- if ((instructionNode.extraArguments ?? []).length === 0) {
941
- return fragment("");
942
- }
1070
+ const instructionNode = getLastNodeFromPath9(instructionPath);
1071
+ if ((instructionNode.extraArguments ?? []).length === 0) return;
943
1072
  const instructionExtraName = nameApi.instructionExtraType(instructionNode.name);
944
- return pipe11(
945
- fragmentFromTemplate("instructionExtraArgs.njk", {
946
- looseName: nameApi.dataArgsType(instructionExtraName),
947
- manifest: extraArgsManifest,
948
- strictName: nameApi.dataType(instructionExtraName)
949
- }),
950
- (f) => mergeFragmentImports(f, [extraArgsManifest.looseType.imports])
951
- );
1073
+ const looseName = nameApi.dataArgsType(instructionExtraName);
1074
+ return mapFragmentContent3(extraArgsManifest.looseType, (c) => `export type ${looseName} = ${c};`);
952
1075
  }
953
1076
 
954
1077
  // src/fragments/instructionFunction.ts
@@ -956,132 +1079,106 @@ import { camelCase as camelCase9, isNode as isNode12, isNodeFilter as isNodeFilt
956
1079
  import { mapFragmentContent as mapFragmentContent7 } from "@codama/renderers-core";
957
1080
  import {
958
1081
  findProgramNodeFromPath as findProgramNodeFromPath3,
959
- getLastNodeFromPath as getLastNodeFromPath12,
960
- pipe as pipe15
1082
+ getLastNodeFromPath as getLastNodeFromPath13,
1083
+ pipe as pipe8
961
1084
  } from "@codama/visitors-core";
962
1085
 
963
1086
  // src/fragments/instructionInputResolved.ts
964
1087
  import { camelCase as camelCase6, isNode as isNode9, parseOptionalAccountStrategy } from "@codama/nodes";
965
1088
  import { mapFragmentContent as mapFragmentContent5 } from "@codama/renderers-core";
966
- import { getLastNodeFromPath as getLastNodeFromPath9 } from "@codama/visitors-core";
1089
+ import { getLastNodeFromPath as getLastNodeFromPath10 } from "@codama/visitors-core";
967
1090
 
968
1091
  // src/fragments/instructionInputDefault.ts
969
1092
  import { camelCase as camelCase5, isNode as isNode8 } from "@codama/nodes";
970
1093
  import { mapFragmentContent as mapFragmentContent4, setFragmentContent } from "@codama/renderers-core";
971
- import { pipe as pipe12, visit as visit3 } from "@codama/visitors-core";
1094
+ import { pipe as pipe5, visit as visit4 } from "@codama/visitors-core";
972
1095
  function getInstructionInputDefaultFragment(scope) {
973
1096
  const { input, optionalAccountStrategy, asyncResolvers, useAsync, nameApi, typeManifestVisitor, getImportFrom } = scope;
974
1097
  if (!input.defaultValue) {
975
- return fragment("");
1098
+ return fragment``;
976
1099
  }
977
1100
  if (!useAsync && isAsyncDefaultValue(input.defaultValue, asyncResolvers)) {
978
- return fragment("");
1101
+ return fragment``;
979
1102
  }
980
1103
  const { defaultValue } = input;
981
1104
  const defaultFragment = (renderedValue, isWritable) => {
982
1105
  const inputName = camelCase5(input.name);
983
1106
  if (input.kind === "instructionAccountNode" && isNode8(defaultValue, "resolverValueNode")) {
984
- return fragment(`accounts.${inputName} = { ...accounts.${inputName}, ...${renderedValue} };`);
1107
+ return fragment`accounts.${inputName} = { ...accounts.${inputName}, ...${renderedValue} };`;
985
1108
  }
986
1109
  if (input.kind === "instructionAccountNode" && isWritable === void 0) {
987
- return fragment(`accounts.${inputName}.value = ${renderedValue};`);
1110
+ return fragment`accounts.${inputName}.value = ${renderedValue};`;
988
1111
  }
989
1112
  if (input.kind === "instructionAccountNode") {
990
- return fragment(
991
- `accounts.${inputName}.value = ${renderedValue};
992
- accounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`
993
- );
1113
+ return fragment`accounts.${inputName}.value = ${renderedValue};\naccounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`;
994
1114
  }
995
- return fragment(`args.${inputName} = ${renderedValue};`);
1115
+ return fragment`args.${inputName} = ${renderedValue};`;
996
1116
  };
997
1117
  switch (defaultValue.kind) {
998
1118
  case "accountValueNode":
999
1119
  const name = camelCase5(defaultValue.name);
1000
1120
  if (input.kind === "instructionAccountNode" && input.resolvedIsSigner && !input.isSigner) {
1001
- return pipe12(
1121
+ return pipe5(
1002
1122
  defaultFragment(`expectTransactionSigner(accounts.${name}.value).address`),
1003
1123
  (f) => addFragmentImports(f, "shared", ["expectTransactionSigner"])
1004
1124
  );
1005
1125
  }
1006
1126
  if (input.kind === "instructionAccountNode") {
1007
- return pipe12(
1127
+ return pipe5(
1008
1128
  defaultFragment(`expectSome(accounts.${name}.value)`),
1009
1129
  (f) => addFragmentImports(f, "shared", ["expectSome"])
1010
1130
  );
1011
1131
  }
1012
- return pipe12(
1132
+ return pipe5(
1013
1133
  defaultFragment(`expectAddress(accounts.${name}.value)`),
1014
1134
  (f) => addFragmentImports(f, "shared", ["expectAddress"])
1015
1135
  );
1016
1136
  case "pdaValueNode":
1017
1137
  if (isNode8(defaultValue.pda, "pdaNode")) {
1018
- const pdaProgram = defaultValue.pda.programId ? pipe12(
1019
- fragment(`'${defaultValue.pda.programId}' as Address<'${defaultValue.pda.programId}'>`),
1138
+ const pdaProgram = defaultValue.pda.programId ? pipe5(
1139
+ fragment`'${defaultValue.pda.programId}' as Address<'${defaultValue.pda.programId}'>`,
1020
1140
  (f) => addFragmentImports(f, "solanaAddresses", ["type Address"])
1021
- ) : fragment("programAddress");
1141
+ ) : fragment`programAddress`;
1022
1142
  const pdaSeeds2 = defaultValue.pda.seeds.flatMap((seed) => {
1023
1143
  if (isNode8(seed, "constantPdaSeedNode") && isNode8(seed.value, "programIdValueNode")) {
1024
1144
  return [
1025
- pipe12(
1026
- fragment(`getAddressEncoder().encode(${pdaProgram.content})`),
1027
- (f) => mergeFragmentImports(f, [pdaProgram.imports]),
1145
+ pipe5(
1146
+ fragment`getAddressEncoder().encode(${pdaProgram})`,
1028
1147
  (f) => addFragmentImports(f, "solanaAddresses", ["getAddressEncoder"])
1029
1148
  )
1030
1149
  ];
1031
1150
  }
1032
1151
  if (isNode8(seed, "constantPdaSeedNode") && !isNode8(seed.value, "programIdValueNode")) {
1033
- const typeManifest2 = visit3(seed.type, typeManifestVisitor);
1034
- const valueManifest2 = visit3(seed.value, typeManifestVisitor);
1035
- return [
1036
- pipe12(
1037
- fragment(`${typeManifest2.encoder.content}.encode(${valueManifest2.value.content})`),
1038
- (f) => mergeFragmentImports(f, [
1039
- typeManifest2.encoder.imports,
1040
- valueManifest2.value.imports
1041
- ])
1042
- )
1043
- ];
1152
+ const typeManifest2 = visit4(seed.type, typeManifestVisitor);
1153
+ const valueManifest2 = visit4(seed.value, typeManifestVisitor);
1154
+ return [fragment`${typeManifest2.encoder}.encode(${valueManifest2.value})`];
1044
1155
  }
1045
1156
  if (isNode8(seed, "variablePdaSeedNode")) {
1046
- const typeManifest2 = visit3(seed.type, typeManifestVisitor);
1157
+ const typeManifest2 = visit4(seed.type, typeManifestVisitor);
1047
1158
  const valueSeed = defaultValue.seeds.find((s) => s.name === seed.name)?.value;
1048
1159
  if (!valueSeed) return [];
1049
1160
  if (isNode8(valueSeed, "accountValueNode")) {
1050
1161
  return [
1051
- pipe12(
1052
- fragment(
1053
- `${typeManifest2.encoder.content}.encode(expectAddress(accounts.${camelCase5(valueSeed.name)}.value))`
1054
- ),
1055
- (f) => mergeFragmentImports(f, [typeManifest2.encoder.imports]),
1162
+ pipe5(
1163
+ fragment`${typeManifest2.encoder}.encode(expectAddress(accounts.${camelCase5(valueSeed.name)}.value))`,
1056
1164
  (f) => addFragmentImports(f, "shared", ["expectAddress"])
1057
1165
  )
1058
1166
  ];
1059
1167
  }
1060
1168
  if (isNode8(valueSeed, "argumentValueNode")) {
1061
1169
  return [
1062
- pipe12(
1063
- fragment(
1064
- `${typeManifest2.encoder.content}.encode(expectSome(args.${camelCase5(valueSeed.name)}))`
1065
- ),
1066
- (f) => mergeFragmentImports(f, [typeManifest2.encoder.imports]),
1170
+ pipe5(
1171
+ fragment`${typeManifest2.encoder}.encode(expectSome(args.${camelCase5(valueSeed.name)}))`,
1067
1172
  (f) => addFragmentImports(f, "shared", ["expectSome"])
1068
1173
  )
1069
1174
  ];
1070
1175
  }
1071
- const valueManifest2 = visit3(valueSeed, typeManifestVisitor);
1072
- return [
1073
- pipe12(
1074
- fragment(`${typeManifest2.encoder.content}.encode(${valueManifest2.value.content})`),
1075
- (f) => mergeFragmentImports(f, [
1076
- typeManifest2.encoder.imports,
1077
- valueManifest2.value.imports
1078
- ])
1079
- )
1080
- ];
1176
+ const valueManifest2 = visit4(valueSeed, typeManifestVisitor);
1177
+ return [fragment`${typeManifest2.encoder}.encode(${valueManifest2.value})`];
1081
1178
  }
1082
1179
  return [];
1083
1180
  });
1084
- return pipe12(
1181
+ return pipe5(
1085
1182
  mergeFragments([pdaProgram, ...pdaSeeds2], ([p, ...s]) => {
1086
1183
  const programAddress2 = p === "programAddress" ? p : `programAddress: ${p}`;
1087
1184
  return `await getProgramDerivedAddress({ ${programAddress2}, seeds: [${s.join(", ")}] })`;
@@ -1094,23 +1191,23 @@ accounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`
1094
1191
  const pdaArgs = [];
1095
1192
  const pdaSeeds = defaultValue.seeds.map((seed) => {
1096
1193
  if (isNode8(seed.value, "accountValueNode")) {
1097
- return pipe12(
1098
- fragment(`${seed.name}: expectAddress(accounts.${camelCase5(seed.value.name)}.value)`),
1194
+ return pipe5(
1195
+ fragment`${seed.name}: expectAddress(accounts.${camelCase5(seed.value.name)}.value)`,
1099
1196
  (f) => addFragmentImports(f, "shared", ["expectAddress"])
1100
1197
  );
1101
1198
  }
1102
1199
  if (isNode8(seed.value, "argumentValueNode")) {
1103
- return pipe12(
1104
- fragment(`${seed.name}: expectSome(args.${camelCase5(seed.value.name)})`),
1200
+ return pipe5(
1201
+ fragment`${seed.name}: expectSome(args.${camelCase5(seed.value.name)})`,
1105
1202
  (f) => addFragmentImports(f, "shared", ["expectSome"])
1106
1203
  );
1107
1204
  }
1108
- return pipe12(
1109
- visit3(seed.value, typeManifestVisitor).value,
1205
+ return pipe5(
1206
+ visit4(seed.value, typeManifestVisitor).value,
1110
1207
  (f) => mapFragmentContent4(f, (c) => `${seed.name}: ${c}`)
1111
1208
  );
1112
1209
  });
1113
- const pdaSeedsFragment = pipe12(
1210
+ const pdaSeedsFragment = pipe5(
1114
1211
  mergeFragments(pdaSeeds, (renders) => renders.join(", ")),
1115
1212
  (f) => mapFragmentContent4(f, (c) => `{ ${c} }`)
1116
1213
  );
@@ -1118,44 +1215,44 @@ accounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`
1118
1215
  pdaArgs.push(pdaSeedsFragment.content);
1119
1216
  }
1120
1217
  const module = getImportFrom(defaultValue.pda);
1121
- return pipe12(
1218
+ return pipe5(
1122
1219
  defaultFragment(`await ${pdaFunction}(${pdaArgs.join(", ")})`),
1123
1220
  (f) => mergeFragmentImports(f, [pdaSeedsFragment.imports]),
1124
1221
  (f) => addFragmentImports(f, module, [pdaFunction])
1125
1222
  );
1126
1223
  case "publicKeyValueNode":
1127
- return pipe12(
1224
+ return pipe5(
1128
1225
  defaultFragment(`'${defaultValue.publicKey}' as Address<'${defaultValue.publicKey}'>`),
1129
1226
  (f) => addFragmentImports(f, "solanaAddresses", ["type Address"])
1130
1227
  );
1131
1228
  case "programLinkNode":
1132
1229
  const programAddress = nameApi.programAddressConstant(defaultValue.name);
1133
- return pipe12(
1230
+ return pipe5(
1134
1231
  defaultFragment(programAddress, false),
1135
1232
  (f) => addFragmentImports(f, getImportFrom(defaultValue), [programAddress])
1136
1233
  );
1137
1234
  case "programIdValueNode":
1138
1235
  if (optionalAccountStrategy === "programId" && input.kind === "instructionAccountNode" && input.isOptional) {
1139
- return fragment("");
1236
+ return fragment``;
1140
1237
  }
1141
1238
  return defaultFragment("programAddress", false);
1142
1239
  case "identityValueNode":
1143
1240
  case "payerValueNode":
1144
- return fragment("");
1241
+ return fragment``;
1145
1242
  case "accountBumpValueNode":
1146
- return pipe12(
1243
+ return pipe5(
1147
1244
  defaultFragment(`expectProgramDerivedAddress(accounts.${camelCase5(defaultValue.name)}.value)[1]`),
1148
1245
  (f) => addFragmentImports(f, "shared", ["expectProgramDerivedAddress"])
1149
1246
  );
1150
1247
  case "argumentValueNode":
1151
- return pipe12(
1248
+ return pipe5(
1152
1249
  defaultFragment(`expectSome(args.${camelCase5(defaultValue.name)})`),
1153
1250
  (f) => addFragmentImports(f, "shared", ["expectSome"])
1154
1251
  );
1155
1252
  case "resolverValueNode":
1156
1253
  const resolverFunction = nameApi.resolverFunction(defaultValue.name);
1157
1254
  const resolverAwait = useAsync && asyncResolvers.includes(defaultValue.name) ? "await " : "";
1158
- return pipe12(
1255
+ return pipe5(
1159
1256
  defaultFragment(`${resolverAwait}${resolverFunction}(resolverScope)`),
1160
1257
  (f) => addFragmentImports(f, getImportFrom(defaultValue), [resolverFunction]),
1161
1258
  (f) => addFragmentFeatures(f, ["instruction:resolverScopeVariable"])
@@ -1170,9 +1267,9 @@ accounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`
1170
1267
  defaultValue: defaultValue.ifFalse
1171
1268
  });
1172
1269
  if (!ifTrueRenderer && !ifFalseRenderer) {
1173
- return fragment("");
1270
+ return fragment``;
1174
1271
  }
1175
- let conditionalFragment = fragment("");
1272
+ let conditionalFragment = fragment``;
1176
1273
  if (ifTrueRenderer) {
1177
1274
  conditionalFragment = mergeFragments([conditionalFragment, ifTrueRenderer], (c) => c[0]);
1178
1275
  }
@@ -1184,7 +1281,7 @@ accounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`
1184
1281
  if (isNode8(defaultValue.condition, "resolverValueNode")) {
1185
1282
  const conditionalResolverFunction = nameApi.resolverFunction(defaultValue.condition.name);
1186
1283
  const module2 = getImportFrom(defaultValue.condition);
1187
- conditionalFragment = pipe12(
1284
+ conditionalFragment = pipe5(
1188
1285
  conditionalFragment,
1189
1286
  (f) => addFragmentImports(f, module2, [conditionalResolverFunction]),
1190
1287
  (f) => addFragmentFeatures(f, ["instruction:resolverScopeVariable"])
@@ -1195,7 +1292,7 @@ accounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`
1195
1292
  } else {
1196
1293
  const comparedInputName = isNode8(defaultValue.condition, "accountValueNode") ? `accounts.${camelCase5(defaultValue.condition.name)}.value` : `args.${camelCase5(defaultValue.condition.name)}`;
1197
1294
  if (defaultValue.value) {
1198
- const comparedValue = visit3(defaultValue.value, typeManifestVisitor).value;
1295
+ const comparedValue = visit4(defaultValue.value, typeManifestVisitor).value;
1199
1296
  conditionalFragment = mergeFragments([conditionalFragment, comparedValue], (c) => c[0]);
1200
1297
  const operator = negatedCondition ? "!==" : "===";
1201
1298
  condition = `${comparedInputName} ${operator} ${comparedValue.content}`;
@@ -1220,8 +1317,8 @@ ${ifTrueRenderer ? ifTrueRenderer.content : ifFalseRenderer?.content}
1220
1317
  }`
1221
1318
  );
1222
1319
  default:
1223
- const valueManifest = visit3(defaultValue, typeManifestVisitor).value;
1224
- return pipe12(valueManifest, (f) => mapFragmentContent4(f, (c) => defaultFragment(c).content));
1320
+ const valueManifest = visit4(defaultValue, typeManifestVisitor).value;
1321
+ return pipe5(valueManifest, (f) => mapFragmentContent4(f, (c) => defaultFragment(c).content));
1225
1322
  }
1226
1323
  }
1227
1324
  function renderNestedInstructionDefault(scope) {
@@ -1235,7 +1332,7 @@ function renderNestedInstructionDefault(scope) {
1235
1332
 
1236
1333
  // src/fragments/instructionInputResolved.ts
1237
1334
  function getInstructionInputResolvedFragment(scope) {
1238
- const instructionNode = getLastNodeFromPath9(scope.instructionPath);
1335
+ const instructionNode = getLastNodeFromPath10(scope.instructionPath);
1239
1336
  const resolvedInputFragments = scope.resolvedInputs.flatMap((input) => {
1240
1337
  const inputFragment = getInstructionInputDefaultFragment({
1241
1338
  ...scope,
@@ -1256,9 +1353,9 @@ ${c}
1256
1353
  ];
1257
1354
  });
1258
1355
  if (resolvedInputFragments.length === 0) {
1259
- return fragment("");
1356
+ return fragment``;
1260
1357
  }
1261
- return mergeFragments([fragment("// Resolve default values."), ...resolvedInputFragments], (c) => c.join("\n"));
1358
+ return mergeFragments([fragment`// Resolve default values.`, ...resolvedInputFragments], (c) => c.join("\n"));
1262
1359
  }
1263
1360
 
1264
1361
  // src/fragments/instructionInputType.ts
@@ -1266,99 +1363,70 @@ import {
1266
1363
  camelCase as camelCase7,
1267
1364
  getAllInstructionArguments,
1268
1365
  isNode as isNode10,
1269
- parseDocs,
1270
1366
  pascalCase as pascalCase4
1271
1367
  } from "@codama/nodes";
1272
1368
  import { mapFragmentContent as mapFragmentContent6 } from "@codama/renderers-core";
1273
1369
  import {
1274
- getLastNodeFromPath as getLastNodeFromPath10,
1275
- pipe as pipe13
1370
+ getLastNodeFromPath as getLastNodeFromPath11,
1371
+ pipe as pipe6
1276
1372
  } from "@codama/visitors-core";
1277
1373
  function getInstructionInputTypeFragment(scope) {
1278
1374
  const { instructionPath, useAsync, nameApi } = scope;
1279
- const instructionNode = getLastNodeFromPath10(instructionPath);
1375
+ const instructionNode = getLastNodeFromPath11(instructionPath);
1280
1376
  const instructionInputType = useAsync ? nameApi.instructionAsyncInputType(instructionNode.name) : nameApi.instructionSyncInputType(instructionNode.name);
1281
- const accountsFragment = getAccountsFragment(scope);
1282
1377
  const [dataArgumentsFragment, customDataArgumentsFragment] = getDataArgumentsFragments(scope);
1283
- const extraArgumentsFragment = getExtraArgumentsFragment(scope);
1284
- const remainingAccountsFragment = getRemainingAccountsFragment(instructionNode);
1285
- return pipe13(
1286
- fragmentFromTemplate("instructionInputType.njk", {
1287
- accountsFragment: accountsFragment.content,
1288
- customDataArgumentsFragment: customDataArgumentsFragment.content,
1289
- dataArgumentsFragment: dataArgumentsFragment.content,
1290
- extraArgumentsFragment: extraArgumentsFragment.content,
1291
- instruction: instructionNode,
1292
- instructionInputType,
1293
- remainingAccountsFragment: remainingAccountsFragment.content
1294
- }),
1295
- (f) => mergeFragmentImports(f, [
1296
- accountsFragment.imports,
1297
- dataArgumentsFragment.imports,
1298
- customDataArgumentsFragment.imports,
1299
- extraArgumentsFragment.imports,
1300
- remainingAccountsFragment.imports
1301
- ]),
1302
- (f) => addFragmentImports(f, "solanaAddresses", ["type Address"])
1378
+ let accountTypeParams = "";
1379
+ if (instructionNode.accounts.length > 0) {
1380
+ accountTypeParams = instructionNode.accounts.map((account) => `TAccount${pascalCase4(account.name)} extends string = string`).join(", ");
1381
+ accountTypeParams = `<${accountTypeParams}>`;
1382
+ }
1383
+ const typeBodyFragment = mergeFragments(
1384
+ [
1385
+ getAccountsFragment(scope),
1386
+ dataArgumentsFragment,
1387
+ getExtraArgumentsFragment(scope),
1388
+ getRemainingAccountsFragment(instructionNode)
1389
+ ],
1390
+ (c) => c.join("\n")
1303
1391
  );
1392
+ return fragment`export type ${instructionInputType}${accountTypeParams} = ${customDataArgumentsFragment} {
1393
+ ${typeBodyFragment}
1394
+ }`;
1304
1395
  }
1305
1396
  function getAccountsFragment(scope) {
1306
1397
  const { instructionPath, resolvedInputs, useAsync, asyncResolvers } = scope;
1307
- const instructionNode = getLastNodeFromPath10(instructionPath);
1398
+ const instructionNode = getLastNodeFromPath11(instructionPath);
1308
1399
  const fragments = instructionNode.accounts.map((account) => {
1309
1400
  const resolvedAccount = resolvedInputs.find(
1310
1401
  (input) => input.kind === "instructionAccountNode" && input.name === account.name
1311
1402
  );
1312
1403
  const hasDefaultValue = !!resolvedAccount.defaultValue && !isNode10(resolvedAccount.defaultValue, ["identityValueNode", "payerValueNode"]) && (useAsync || !isAsyncDefaultValue(resolvedAccount.defaultValue, asyncResolvers));
1313
- const accountDocs = parseDocs(account.docs);
1314
- const docblock = accountDocs.length > 0 ? jsDocblock(accountDocs) : "";
1404
+ const docs = getDocblockFragment(account.docs ?? [], true);
1315
1405
  const optionalSign = hasDefaultValue || resolvedAccount.isOptional ? "?" : "";
1316
- return mapFragmentContent6(
1317
- getAccountTypeFragment2(resolvedAccount),
1318
- (c) => `${docblock}${camelCase7(account.name)}${optionalSign}: ${c};`
1319
- );
1406
+ return fragment`${docs}${camelCase7(account.name)}${optionalSign}: ${getAccountTypeFragment2(resolvedAccount)};`;
1320
1407
  });
1321
1408
  return mergeFragments(fragments, (c) => c.join("\n"));
1322
1409
  }
1323
1410
  function getAccountTypeFragment2(account) {
1324
1411
  const typeParam = `TAccount${pascalCase4(account.name)}`;
1325
- if (account.isPda && account.isSigner === false) {
1326
- return pipe13(
1327
- fragment(`ProgramDerivedAddress<${typeParam}>`),
1328
- (f) => addFragmentImports(f, "solanaAddresses", ["type ProgramDerivedAddress"])
1329
- );
1330
- }
1331
- if (account.isPda && account.isSigner === "either") {
1332
- return pipe13(
1333
- fragment(`ProgramDerivedAddress<${typeParam}> | TransactionSigner<${typeParam}>`),
1334
- (f) => addFragmentImports(f, "solanaAddresses", ["type ProgramDerivedAddress"]),
1335
- (f) => addFragmentImports(f, "solanaSigners", ["type TransactionSigner"])
1336
- );
1337
- }
1338
- if (account.isSigner === "either") {
1339
- return pipe13(
1340
- fragment(`Address<${typeParam}> | TransactionSigner<${typeParam}>`),
1341
- (f) => addFragmentImports(f, "solanaAddresses", ["type Address"]),
1342
- (f) => addFragmentImports(f, "solanaSigners", ["type TransactionSigner"])
1343
- );
1344
- }
1345
- if (account.isSigner) {
1346
- return pipe13(
1347
- fragment(`TransactionSigner<${typeParam}>`),
1348
- (f) => addFragmentImports(f, "solanaSigners", ["type TransactionSigner"])
1349
- );
1350
- }
1351
- return pipe13(fragment(`Address<${typeParam}>`), (f) => addFragmentImports(f, "solanaAddresses", ["type Address"]));
1412
+ const address = use("type Address", "solanaAddresses");
1413
+ const signer = use("type TransactionSigner", "solanaSigners");
1414
+ const pda = use("type ProgramDerivedAddress", "solanaAddresses");
1415
+ if (account.isPda && account.isSigner === false) return fragment`${pda}<${typeParam}>`;
1416
+ if (account.isPda && account.isSigner === "either") return fragment`${pda}<${typeParam}> | ${signer}<${typeParam}>`;
1417
+ if (account.isSigner === "either") return fragment`${address}<${typeParam}> | ${signer}<${typeParam}>`;
1418
+ if (account.isSigner) return fragment`${signer}<${typeParam}>`;
1419
+ return fragment`${address}<${typeParam}>`;
1352
1420
  }
1353
1421
  function getDataArgumentsFragments(scope) {
1354
1422
  const { instructionPath, nameApi } = scope;
1355
- const instructionNode = getLastNodeFromPath10(instructionPath);
1423
+ const instructionNode = getLastNodeFromPath11(instructionPath);
1356
1424
  const customData = scope.customInstructionData.get(instructionNode.name);
1357
1425
  if (customData) {
1358
1426
  return [
1359
- fragment(""),
1360
- pipe13(
1361
- fragment(nameApi.dataArgsType(customData.importAs)),
1427
+ void 0,
1428
+ pipe6(
1429
+ fragment`${nameApi.dataArgsType(customData.importAs)}`,
1362
1430
  (f) => mergeFragmentImports(f, [scope.dataArgsManifest.looseType.imports]),
1363
1431
  (f) => mapFragmentContent6(f, (c) => `${c} & `)
1364
1432
  )
@@ -1367,20 +1435,21 @@ function getDataArgumentsFragments(scope) {
1367
1435
  const instructionDataName = nameApi.instructionDataType(instructionNode.name);
1368
1436
  const dataArgsType = nameApi.dataArgsType(instructionDataName);
1369
1437
  const fragments = instructionNode.arguments.flatMap((arg) => {
1370
- const argFragment = getArgumentFragment(arg, fragment(dataArgsType), scope.resolvedInputs, scope.renamedArgs);
1438
+ const argFragment = getArgumentFragment(arg, dataArgsType, scope.resolvedInputs, scope.renamedArgs);
1371
1439
  return argFragment ? [argFragment] : [];
1372
1440
  });
1373
- return [mergeFragments(fragments, (c) => c.join("\n")), fragment("")];
1441
+ return [fragments.length === 0 ? void 0 : mergeFragments(fragments, (c) => c.join("\n")), fragment``];
1374
1442
  }
1375
1443
  function getExtraArgumentsFragment(scope) {
1376
1444
  const { instructionPath, nameApi } = scope;
1377
- const instructionNode = getLastNodeFromPath10(instructionPath);
1445
+ const instructionNode = getLastNodeFromPath11(instructionPath);
1378
1446
  const instructionExtraName = nameApi.instructionExtraType(instructionNode.name);
1379
1447
  const extraArgsType = nameApi.dataArgsType(instructionExtraName);
1380
1448
  const fragments = (instructionNode.extraArguments ?? []).flatMap((arg) => {
1381
- const argFragment = getArgumentFragment(arg, fragment(extraArgsType), scope.resolvedInputs, scope.renamedArgs);
1449
+ const argFragment = getArgumentFragment(arg, extraArgsType, scope.resolvedInputs, scope.renamedArgs);
1382
1450
  return argFragment ? [argFragment] : [];
1383
1451
  });
1452
+ if (fragments.length === 0) return;
1384
1453
  return mergeFragments(fragments, (c) => c.join("\n"));
1385
1454
  }
1386
1455
  function getArgumentFragment(arg, argsType, resolvedInputs, renamedArgs) {
@@ -1390,10 +1459,7 @@ function getArgumentFragment(arg, argsType, resolvedInputs, renamedArgs) {
1390
1459
  if (arg.defaultValue && arg.defaultValueStrategy === "omitted") return null;
1391
1460
  const renamedName = renamedArgs.get(arg.name) ?? arg.name;
1392
1461
  const optionalSign = arg.defaultValue || resolvedArg?.defaultValue ? "?" : "";
1393
- return mapFragmentContent6(
1394
- argsType,
1395
- (c) => `${camelCase7(renamedName)}${optionalSign}: ${c}["${camelCase7(arg.name)}"];`
1396
- );
1462
+ return fragment`${camelCase7(renamedName)}${optionalSign}: ${argsType}["${camelCase7(arg.name)}"];`;
1397
1463
  }
1398
1464
  function getRemainingAccountsFragment(instructionNode) {
1399
1465
  const fragments = (instructionNode.remainingAccounts ?? []).flatMap((remainingAccountsNode) => {
@@ -1404,24 +1470,15 @@ function getRemainingAccountsFragment(instructionNode) {
1404
1470
  if (argumentExists) return [];
1405
1471
  const isSigner = remainingAccountsNode.isSigner ?? false;
1406
1472
  const optionalSign = remainingAccountsNode.isOptional ?? false ? "?" : "";
1407
- const signerFragment = pipe13(
1408
- fragment(`TransactionSigner`),
1409
- (f) => addFragmentImports(f, "solanaSigners", ["type TransactionSigner"])
1410
- );
1411
- const addressFragment = pipe13(
1412
- fragment(`Address`),
1413
- (f) => addFragmentImports(f, "solanaAddresses", ["type Address"])
1414
- );
1415
- return mapFragmentContent6(
1416
- (() => {
1417
- if (isSigner === "either") {
1418
- return mergeFragments([signerFragment, addressFragment], (c) => c.join(" | "));
1419
- }
1420
- return isSigner ? signerFragment : addressFragment;
1421
- })(),
1422
- (c) => `${camelCase7(name)}${optionalSign}: Array<${c}>;`
1423
- );
1473
+ const signerFragment = use("type TransactionSigner", "solanaSigners");
1474
+ const addressFragment = use("type Address", "solanaAddresses");
1475
+ const typeFragment = (() => {
1476
+ if (isSigner === "either") return fragment`${signerFragment} | ${addressFragment}`;
1477
+ return isSigner ? signerFragment : addressFragment;
1478
+ })();
1479
+ return fragment`${camelCase7(name)}${optionalSign}: Array<${typeFragment}>;`;
1424
1480
  });
1481
+ if (fragments.length === 0) return;
1425
1482
  return mergeFragments(fragments, (c) => c.join("\n"));
1426
1483
  }
1427
1484
 
@@ -1432,12 +1489,12 @@ import {
1432
1489
  getAllInstructionArguments as getAllInstructionArguments2,
1433
1490
  isNode as isNode11
1434
1491
  } from "@codama/nodes";
1435
- import { getLastNodeFromPath as getLastNodeFromPath11, pipe as pipe14 } from "@codama/visitors-core";
1492
+ import { getLastNodeFromPath as getLastNodeFromPath12, pipe as pipe7 } from "@codama/visitors-core";
1436
1493
  function getInstructionRemainingAccountsFragment(scope) {
1437
- const { remainingAccounts } = getLastNodeFromPath11(scope.instructionPath);
1494
+ const { remainingAccounts } = getLastNodeFromPath12(scope.instructionPath);
1438
1495
  const fragments = (remainingAccounts ?? []).flatMap((a) => getRemainingAccountsFragment2(a, scope));
1439
- if (fragments.length === 0) return fragment("");
1440
- return pipe14(
1496
+ if (fragments.length === 0) return;
1497
+ return pipe7(
1441
1498
  mergeFragments(
1442
1499
  fragments,
1443
1500
  (c) => `// Remaining accounts.
@@ -1460,75 +1517,50 @@ function getRemainingAccountsFragment2(remainingAccounts, scope) {
1460
1517
  return [remainingAccountsFragment];
1461
1518
  }
1462
1519
  function getArgumentValueNodeFragment2(remainingAccounts, scope) {
1463
- const instructionNode = getLastNodeFromPath11(scope.instructionPath);
1520
+ const instructionNode = getLastNodeFromPath12(scope.instructionPath);
1464
1521
  assertIsNode2(remainingAccounts.value, "argumentValueNode");
1465
1522
  const argumentName = camelCase8(remainingAccounts.value.name);
1466
1523
  const isOptional = remainingAccounts.isOptional ?? false;
1467
1524
  const isSigner = remainingAccounts.isSigner ?? false;
1468
1525
  const isWritable = remainingAccounts.isWritable ?? false;
1469
- const nonSignerRole = isWritable ? "AccountRole.WRITABLE" : "AccountRole.READONLY";
1470
- const signerRole = isWritable ? "AccountRole.WRITABLE_SIGNER" : "AccountRole.READONLY_SIGNER";
1526
+ const accountRole = use("AccountRole", "solanaInstructions");
1527
+ const nonSignerRole = isWritable ? fragment`${accountRole}.WRITABLE` : fragment`${accountRole}.READONLY`;
1528
+ const signerRole = isWritable ? fragment`${accountRole}.WRITABLE_SIGNER` : fragment`${accountRole}.READONLY_SIGNER`;
1471
1529
  const role = isSigner === true ? signerRole : nonSignerRole;
1472
1530
  const argumentArray = isOptional ? `(args.${argumentName} ?? [])` : `args.${argumentName}`;
1473
1531
  const allArguments = getAllInstructionArguments2(instructionNode);
1474
1532
  const argumentExists = allArguments.some((arg) => arg.name === remainingAccounts.value.name);
1475
1533
  if (argumentExists || isSigner === false) {
1476
- return pipe14(
1477
- fragment(`${argumentArray}.map((address) => ({ address, role: ${role} }))`),
1478
- (f) => addFragmentImports(f, "solanaInstructions", ["AccountRole"])
1479
- );
1534
+ return fragment`${argumentArray}.map((address) => ({ address, role: ${role} }))`;
1480
1535
  }
1481
1536
  if (isSigner === "either") {
1482
- return pipe14(
1483
- fragment(
1484
- `${argumentArray}.map((addressOrSigner) => (isTransactionSigner(addressOrSigner)
1485
- ? { address: addressOrSigner.address, role: ${role}, signer: addressOrSigner }
1486
- : { address: addressOrSigner, role: ${role} }
1487
- ))`
1488
- ),
1489
- (f) => addFragmentImports(f, "solanaInstructions", ["AccountRole"]),
1490
- (f) => addFragmentImports(f, "shared", ["isTransactionSigner"])
1491
- );
1537
+ return fragment`${argumentArray}.map((addressOrSigner) => (${use("isTransactionSigner", "shared")}(addressOrSigner) ? { address: addressOrSigner.address, role: ${role}, signer: addressOrSigner } : { address: addressOrSigner, role: ${role} }))`;
1492
1538
  }
1493
- return pipe14(
1494
- fragment(`${argumentArray}.map((signer) => ({ address: signer.address, role: ${signerRole}, signer }))`),
1495
- (f) => addFragmentImports(f, "solanaInstructions", ["AccountRole"])
1496
- );
1539
+ return fragment`${argumentArray}.map((signer) => ({ address: signer.address, role: ${signerRole}, signer }))`;
1497
1540
  }
1498
1541
  function getResolverValueNodeFragment2(remainingAccounts, scope) {
1499
1542
  assertIsNode2(remainingAccounts.value, "resolverValueNode");
1500
1543
  const isAsync = scope.asyncResolvers.includes(remainingAccounts.value.name);
1501
1544
  if (!scope.useAsync && isAsync) return null;
1502
1545
  const awaitKeyword = scope.useAsync && isAsync ? "await " : "";
1503
- const functionName = scope.nameApi.resolverFunction(remainingAccounts.value.name);
1504
- const module = scope.getImportFrom(remainingAccounts.value);
1505
- return pipe14(
1506
- fragment(`${awaitKeyword}${functionName}(resolverScope)`),
1507
- (f) => addFragmentImports(f, module, [functionName]),
1546
+ const functionName = use(
1547
+ scope.nameApi.resolverFunction(remainingAccounts.value.name),
1548
+ scope.getImportFrom(remainingAccounts.value)
1549
+ );
1550
+ return pipe7(
1551
+ fragment`${awaitKeyword}${functionName}(resolverScope)`,
1508
1552
  (f) => addFragmentFeatures(f, ["instruction:resolverScopeVariable"])
1509
1553
  );
1510
1554
  }
1511
1555
 
1512
1556
  // src/fragments/instructionFunction.ts
1513
1557
  function getInstructionFunctionFragment(scope) {
1514
- const {
1515
- useAsync,
1516
- instructionPath,
1517
- resolvedInputs,
1518
- renamedArgs,
1519
- dataArgsManifest,
1520
- asyncResolvers,
1521
- nameApi,
1522
- customInstructionData
1523
- } = scope;
1524
- const instructionNode = getLastNodeFromPath12(instructionPath);
1558
+ const { useAsync, instructionPath, resolvedInputs, renamedArgs, asyncResolvers, nameApi, customInstructionData } = scope;
1559
+ const instructionNode = getLastNodeFromPath13(instructionPath);
1525
1560
  const programNode = findProgramNodeFromPath3(instructionPath);
1526
- if (useAsync && !hasAsyncFunction(instructionNode, resolvedInputs, asyncResolvers)) {
1527
- return fragment("");
1528
- }
1561
+ if (useAsync && !hasAsyncFunction(instructionNode, resolvedInputs, asyncResolvers)) return;
1529
1562
  const customData = customInstructionData.get(instructionNode.name);
1530
1563
  const hasAccounts = instructionNode.accounts.length > 0;
1531
- const hasLegacyOptionalAccounts = instructionNode.optionalAccountStrategy === "omitted" && instructionNode.accounts.some((account) => account.isOptional);
1532
1564
  const instructionDependencies = getInstructionDependencies(instructionNode, asyncResolvers, useAsync);
1533
1565
  const argDependencies = instructionDependencies.filter(isNodeFilter4("argumentValueNode")).map((node) => node.name);
1534
1566
  const hasData = !!customData || instructionNode.arguments.length > 0;
@@ -1546,178 +1578,297 @@ function getInstructionFunctionFragment(scope) {
1546
1578
  const hasRemainingAccountArgs = (instructionNode.remainingAccounts ?? []).filter(({ value }) => isNode12(value, "argumentValueNode")).length > 0;
1547
1579
  const hasAnyArgs = hasDataArgs || hasExtraArgs || hasRemainingAccountArgs;
1548
1580
  const hasInput = hasAccounts || hasAnyArgs;
1549
- const instructionDataName = nameApi.instructionDataType(instructionNode.name);
1550
- const programAddressConstant = nameApi.programAddressConstant(programNode.name);
1551
- const encoderFunction = customData ? dataArgsManifest.encoder.content : `${nameApi.encoderFunction(instructionDataName)}()`;
1552
- const argsTypeFragment = pipe15(
1553
- fragment(customData ? dataArgsManifest.looseType.content : nameApi.dataArgsType(instructionDataName)),
1554
- customData ? (f) => mergeFragmentImports(f, [dataArgsManifest.looseType.imports, dataArgsManifest.encoder.imports]) : (f) => f
1555
- );
1581
+ const programAddressConstant = use(nameApi.programAddressConstant(programNode.name), "generatedPrograms");
1556
1582
  const functionName = useAsync ? nameApi.instructionAsyncFunction(instructionNode.name) : nameApi.instructionSyncFunction(instructionNode.name);
1557
- const typeParamsFragment = getTypeParams(instructionNode, programAddressConstant);
1558
- const instructionTypeFragment = getInstructionType(scope);
1559
- const inputTypeFragment = getInstructionInputTypeFragment(scope);
1560
- const inputTypeCallFragment = getInputTypeCall(scope);
1561
- const renamedArgsText = [...renamedArgs.entries()].map(([k, v]) => `${k}: input.${v}`).join(", ");
1562
1583
  const resolvedInputsFragment = getInstructionInputResolvedFragment(scope);
1563
1584
  const remainingAccountsFragment = getInstructionRemainingAccountsFragment(scope);
1564
1585
  const byteDeltaFragment = getInstructionByteDeltaFragment(scope);
1565
- const resolvedFragment = mergeFragments(
1586
+ const resolvedInputFragment = mergeFragments(
1566
1587
  [resolvedInputsFragment, remainingAccountsFragment, byteDeltaFragment],
1567
1588
  (content) => content.join("\n\n")
1568
1589
  );
1569
- const hasRemainingAccounts = remainingAccountsFragment.content !== "";
1570
- const hasByteDeltas = byteDeltaFragment.content !== "";
1571
- const hasResolver = resolvedFragment.features.has("instruction:resolverScopeVariable");
1572
- const getReturnType = (instructionType) => {
1573
- let returnType = instructionType;
1574
- if (hasByteDeltas) {
1575
- returnType = `${returnType} & InstructionWithByteDelta`;
1576
- }
1577
- return useAsync ? `Promise<${returnType}>` : returnType;
1578
- };
1579
- return pipe15(
1580
- fragmentFromTemplate("instructionFunction.njk", {
1581
- argsTypeFragment: argsTypeFragment.content,
1582
- encoderFunction,
1583
- functionName,
1584
- getReturnType,
1585
- hasAccounts,
1586
- hasAnyArgs,
1587
- hasByteDeltas,
1588
- hasData,
1589
- hasDataArgs,
1590
- hasExtraArgs,
1591
- hasInput,
1592
- hasLegacyOptionalAccounts,
1593
- hasRemainingAccounts,
1594
- hasResolver,
1595
- inputTypeCallFragment: inputTypeCallFragment.content,
1596
- inputTypeFragment: inputTypeFragment.content,
1597
- instruction: instructionNode,
1598
- instructionTypeFragment: instructionTypeFragment.content,
1599
- programAddressConstant,
1600
- renamedArgs: renamedArgsText,
1601
- resolvedFragment: resolvedFragment.content,
1602
- typeParamsFragment: typeParamsFragment.content,
1603
- useAsync
1590
+ const hasRemainingAccounts = !!remainingAccountsFragment;
1591
+ const hasByteDeltas = !!byteDeltaFragment;
1592
+ const hasResolver = resolvedInputFragment.features.has("instruction:resolverScopeVariable");
1593
+ const instructionTypeFragment = getInstructionTypeFragment(scope);
1594
+ const typeParams = getTypeParamsFragment(instructionNode, programAddressConstant);
1595
+ const returnType = getReturnTypeFragment(instructionTypeFragment, hasByteDeltas, useAsync);
1596
+ const inputType = getInstructionInputTypeFragment(scope);
1597
+ const inputArg = mapFragmentContent7(getInputTypeCallFragment(scope), (c) => hasInput ? `input: ${c}, ` : "");
1598
+ const functionBody = mergeFragments(
1599
+ [
1600
+ getProgramAddressInitializationFragment(programAddressConstant),
1601
+ getAccountsInitializationFragment(instructionNode),
1602
+ getArgumentsInitializationFragment(hasAnyArgs, renamedArgs),
1603
+ getResolverScopeInitializationFragment(hasResolver, hasAccounts, hasAnyArgs),
1604
+ resolvedInputFragment,
1605
+ getReturnStatementFragment({
1606
+ ...scope,
1607
+ hasByteDeltas,
1608
+ hasData,
1609
+ hasDataArgs,
1610
+ hasRemainingAccounts,
1611
+ instructionNode,
1612
+ syncReturnTypeFragment: getReturnTypeFragment(instructionTypeFragment, hasByteDeltas, false)
1613
+ })
1614
+ ],
1615
+ (cs) => cs.join("\n\n")
1616
+ );
1617
+ return fragment`${inputType}\n\nexport ${useAsync ? "async " : ""}function ${functionName}${typeParams}(${inputArg}config?: { programAddress?: TProgramAddress } ): ${returnType} {
1618
+ ${functionBody}
1619
+ }`;
1620
+ }
1621
+ function getProgramAddressInitializationFragment(programAddressConstant) {
1622
+ return fragment`// Program address.
1623
+ const programAddress = config?.programAddress ?? ${programAddressConstant};`;
1624
+ }
1625
+ function getAccountsInitializationFragment(instructionNode) {
1626
+ if (instructionNode.accounts.length === 0) return;
1627
+ const accounts = mergeFragments(
1628
+ instructionNode.accounts.map((account) => {
1629
+ const name = camelCase9(account.name);
1630
+ const isWritable = account.isWritable ? "true" : "false";
1631
+ return fragment`${name}: { value: input.${name} ?? null, isWritable: ${isWritable} }`;
1604
1632
  }),
1605
- (f) => mergeFragmentImports(f, [
1606
- typeParamsFragment.imports,
1607
- instructionTypeFragment.imports,
1608
- inputTypeFragment.imports,
1609
- inputTypeCallFragment.imports,
1610
- resolvedFragment.imports,
1611
- argsTypeFragment.imports
1612
- ]),
1613
- (f) => addFragmentImports(f, "generatedPrograms", [programAddressConstant]),
1614
- (f) => addFragmentImports(f, "solanaAddresses", ["type Address"]),
1615
- (f) => hasAccounts ? addFragmentImports(f, "solanaInstructions", ["type AccountMeta"]) : f,
1616
- (f) => hasAccounts ? addFragmentImports(f, "shared", ["getAccountMetaFactory", "type ResolvedAccount"]) : f,
1617
- (f) => hasByteDeltas ? addFragmentImports(f, "shared", ["type InstructionWithByteDelta"]) : f
1633
+ (cs) => cs.join(", ")
1618
1634
  );
1635
+ return fragment` // Original accounts.
1636
+ const originalAccounts = { ${accounts} }
1637
+ const accounts = originalAccounts as Record<keyof typeof originalAccounts, ${use("type ResolvedAccount", "shared")}>;
1638
+ `;
1619
1639
  }
1620
- function getTypeParams(instructionNode, programAddressConstant) {
1621
- const typeParams = instructionNode.accounts.map((account) => `TAccount${pascalCase5(account.name)} extends string`);
1622
- typeParams.push(`TProgramAddress extends Address = typeof ${programAddressConstant}`);
1623
- return pipe15(
1624
- fragment(typeParams.filter((x) => !!x).join(", ")),
1625
- (f) => mapFragmentContent7(f, (c) => `<${c}>`),
1626
- (f) => addFragmentImports(f, "generatedPrograms", [programAddressConstant])
1640
+ function getArgumentsInitializationFragment(hasAnyArgs, renamedArgs) {
1641
+ if (!hasAnyArgs) return;
1642
+ const renamedArgsText = [...renamedArgs.entries()].map(([k, v]) => `${k}: input.${v}`).join(", ");
1643
+ return fragment`// Original args.
1644
+ const args = { ...input, ${renamedArgsText} };
1645
+ `;
1646
+ }
1647
+ function getResolverScopeInitializationFragment(hasResolver, hasAccounts, hasAnyArgs) {
1648
+ if (!hasResolver) return;
1649
+ const resolverAttributes = [
1650
+ "programAddress",
1651
+ ...hasAccounts ? ["accounts"] : [],
1652
+ ...hasAnyArgs ? ["args"] : []
1653
+ ].join(", ");
1654
+ return fragment`// Resolver scope.
1655
+ const resolverScope = { ${resolverAttributes} };`;
1656
+ }
1657
+ function getReturnStatementFragment(scope) {
1658
+ const { instructionNode, hasByteDeltas, hasData, hasDataArgs, hasRemainingAccounts, nameApi } = scope;
1659
+ const optionalAccountStrategy = instructionNode.optionalAccountStrategy ?? "programId";
1660
+ const hasAccounts = instructionNode.accounts.length > 0;
1661
+ const hasLegacyOptionalAccounts = instructionNode.optionalAccountStrategy === "omitted" && instructionNode.accounts.some((account) => account.isOptional);
1662
+ const getAccountMeta = hasAccounts ? fragment`const getAccountMeta = ${use("getAccountMetaFactory", "shared")}(programAddress, '${optionalAccountStrategy}');` : "";
1663
+ const accountItems = [
1664
+ ...instructionNode.accounts.map((account) => `getAccountMeta(accounts.${camelCase9(account.name)})`),
1665
+ ...hasRemainingAccounts ? ["...remainingAccounts"] : []
1666
+ ].join(", ");
1667
+ let accounts;
1668
+ if (hasAccounts && hasLegacyOptionalAccounts) {
1669
+ accounts = fragment`accounts: [${accountItems}].filter(<T>(x: T | undefined): x is T => x !== undefined)`;
1670
+ } else if (hasAccounts) {
1671
+ accounts = fragment`accounts: [${accountItems}]`;
1672
+ } else if (hasRemainingAccounts) {
1673
+ accounts = fragment`accounts: remainingAccounts`;
1674
+ }
1675
+ const customData = scope.customInstructionData.get(instructionNode.name);
1676
+ const instructionDataName = nameApi.instructionDataType(instructionNode.name);
1677
+ const encoderFunctionFragment = customData ? scope.dataArgsManifest.encoder : `${nameApi.encoderFunction(instructionDataName)}()`;
1678
+ const argsTypeFragment = customData ? scope.dataArgsManifest.looseType : nameApi.dataArgsType(instructionDataName);
1679
+ let data;
1680
+ if (hasDataArgs) {
1681
+ data = fragment`data: ${encoderFunctionFragment}.encode(args as ${argsTypeFragment})`;
1682
+ } else if (hasData) {
1683
+ data = fragment`data: ${encoderFunctionFragment}.encode({})`;
1684
+ }
1685
+ const instructionAttributes = pipe8(
1686
+ [accounts, hasByteDeltas ? fragment`byteDelta` : void 0, data, fragment`programAddress`],
1687
+ (fs) => mergeFragments(fs, (cs) => cs.join(", "))
1688
+ );
1689
+ return fragment`${getAccountMeta}\nreturn Object.freeze({ ${instructionAttributes} } as ${scope.syncReturnTypeFragment});`;
1690
+ }
1691
+ function getReturnTypeFragment(instructionTypeFragment, hasByteDeltas, useAsync) {
1692
+ return pipe8(
1693
+ instructionTypeFragment,
1694
+ (f) => hasByteDeltas ? fragment`${f} & ${use("type InstructionWithByteDelta", "shared")}` : f,
1695
+ (f) => useAsync ? fragment`Promise<${f}>` : f
1696
+ );
1697
+ }
1698
+ function getTypeParamsFragment(instructionNode, programAddressConstant) {
1699
+ return mergeFragments(
1700
+ [
1701
+ ...instructionNode.accounts.map((account) => fragment`TAccount${pascalCase5(account.name)} extends string`),
1702
+ fragment`TProgramAddress extends ${use("type Address", "solanaAddresses")} = typeof ${programAddressConstant}`
1703
+ ],
1704
+ (cs) => `<${cs.join(", ")}>`
1627
1705
  );
1628
1706
  }
1629
- function getInstructionType(scope) {
1707
+ function getInstructionTypeFragment(scope) {
1630
1708
  const { instructionPath, nameApi } = scope;
1631
- const instructionNode = getLastNodeFromPath12(instructionPath);
1709
+ const instructionNode = getLastNodeFromPath13(instructionPath);
1632
1710
  const instructionTypeName = nameApi.instructionType(instructionNode.name);
1633
- const programAddressFragment = fragment("TProgramAddress");
1634
1711
  const accountTypeParamsFragments = instructionNode.accounts.map((account) => {
1635
- const typeParam = `TAccount${pascalCase5(account.name)}`;
1712
+ const typeParam = fragment`TAccount${pascalCase5(account.name)}`;
1636
1713
  const camelName = camelCase9(account.name);
1637
1714
  if (account.isSigner === "either") {
1638
- const signerRole = account.isWritable ? "WritableSignerAccount" : "ReadonlySignerAccount";
1639
- return pipe15(
1640
- fragment(
1641
- `typeof input["${camelName}"] extends TransactionSigner<${typeParam}> ? ${signerRole}<${typeParam}> & AccountSignerMeta<${typeParam}> : ${typeParam}`
1642
- ),
1643
- (f) => addFragmentImports(f, "solanaInstructions", [`type ${signerRole}`]),
1644
- (f) => addFragmentImports(f, "solanaSigners", ["type AccountSignerMeta"])
1715
+ const signerRole = use(
1716
+ account.isWritable ? "type WritableSignerAccount" : "type ReadonlySignerAccount",
1717
+ "solanaInstructions"
1718
+ );
1719
+ return pipe8(
1720
+ fragment`typeof input["${camelName}"] extends TransactionSigner<${typeParam}> ? ${signerRole}<${typeParam}> & AccountSignerMeta<${typeParam}> : ${typeParam}`,
1721
+ (f) => addFragmentImports(f, "solanaSigners", ["type AccountSignerMeta", "type TransactionSigner"])
1645
1722
  );
1646
1723
  }
1647
- return fragment(typeParam);
1724
+ return typeParam;
1648
1725
  });
1649
- return pipe15(
1650
- mergeFragments([programAddressFragment, ...accountTypeParamsFragments], (c) => c.join(", ")),
1726
+ return pipe8(
1727
+ mergeFragments([fragment`TProgramAddress`, ...accountTypeParamsFragments], (c) => c.join(", ")),
1651
1728
  (f) => mapFragmentContent7(f, (c) => `${instructionTypeName}<${c}>`)
1652
1729
  );
1653
1730
  }
1654
- function getInputTypeCall(scope) {
1731
+ function getInputTypeCallFragment(scope) {
1655
1732
  const { instructionPath, useAsync, nameApi } = scope;
1656
- const instructionNode = getLastNodeFromPath12(instructionPath);
1733
+ const instructionNode = getLastNodeFromPath13(instructionPath);
1657
1734
  const inputTypeName = useAsync ? nameApi.instructionAsyncInputType(instructionNode.name) : nameApi.instructionSyncInputType(instructionNode.name);
1658
- if (instructionNode.accounts.length === 0) return fragment(inputTypeName);
1735
+ if (instructionNode.accounts.length === 0) return fragment`${inputTypeName}`;
1659
1736
  const accountTypeParams = instructionNode.accounts.map((account) => `TAccount${pascalCase5(account.name)}`).join(", ");
1660
- return fragment(`${inputTypeName}<${accountTypeParams}>`);
1737
+ return fragment`${inputTypeName}<${accountTypeParams}>`;
1661
1738
  }
1662
1739
 
1740
+ // src/fragments/instructionPage.ts
1741
+ import { logWarn } from "@codama/errors";
1742
+ import { camelCase as camelCase11, definedTypeNode as definedTypeNode2, structTypeNodeFromInstructionArgumentNodes as structTypeNodeFromInstructionArgumentNodes3 } from "@codama/nodes";
1743
+ import {
1744
+ findProgramNodeFromPath as findProgramNodeFromPath6,
1745
+ getLastNodeFromPath as getLastNodeFromPath16,
1746
+ visit as visit5
1747
+ } from "@codama/visitors-core";
1748
+
1663
1749
  // src/fragments/instructionParseFunction.ts
1664
- import { findProgramNodeFromPath as findProgramNodeFromPath4, getLastNodeFromPath as getLastNodeFromPath13, pipe as pipe16 } from "@codama/visitors-core";
1750
+ import { camelCase as camelCase10 } from "@codama/nodes";
1751
+ import { findProgramNodeFromPath as findProgramNodeFromPath4, getLastNodeFromPath as getLastNodeFromPath14, pipe as pipe9 } from "@codama/visitors-core";
1665
1752
  function getInstructionParseFunctionFragment(scope) {
1666
- const { instructionPath, dataArgsManifest, nameApi, customInstructionData } = scope;
1667
- const instructionNode = getLastNodeFromPath13(instructionPath);
1668
- const programNode = findProgramNodeFromPath4(instructionPath);
1669
- const customData = customInstructionData.get(instructionNode.name);
1670
- const hasAccounts = instructionNode.accounts.length > 0;
1671
- const hasOptionalAccounts = instructionNode.accounts.some((account) => account.isOptional);
1672
- const minimumNumberOfAccounts = instructionNode.optionalAccountStrategy === "omitted" ? instructionNode.accounts.filter((account) => !account.isOptional).length : instructionNode.accounts.length;
1673
- const hasData = !!customData || instructionNode.arguments.length > 0;
1674
- const instructionDataName = nameApi.instructionDataType(instructionNode.name);
1675
- const programAddressConstant = nameApi.programAddressConstant(programNode.name);
1676
- const dataTypeFragment = customData ? pipe16(
1677
- fragment(dataArgsManifest.strictType.content),
1678
- (f) => mergeFragmentImports(f, [dataArgsManifest.strictType.imports, dataArgsManifest.decoder.imports])
1679
- ) : fragment(nameApi.dataType(instructionDataName));
1680
- const decoderFunction = customData ? dataArgsManifest.decoder.content : `${nameApi.decoderFunction(instructionDataName)}()`;
1681
- return pipe16(
1682
- fragmentFromTemplate("instructionParseFunction.njk", {
1683
- dataTypeFragment: dataTypeFragment.content,
1684
- decoderFunction,
1685
- hasAccounts,
1686
- hasData,
1687
- hasOptionalAccounts,
1688
- instruction: instructionNode,
1689
- instructionParseFunction: nameApi.instructionParseFunction(instructionNode.name),
1690
- instructionParsedType: nameApi.instructionParsedType(instructionNode.name),
1691
- minimumNumberOfAccounts,
1692
- programAddressConstant
1753
+ const instructionNode = getLastNodeFromPath14(scope.instructionPath);
1754
+ const programNode = findProgramNodeFromPath4(scope.instructionPath);
1755
+ const programAddressConstant = use(scope.nameApi.programAddressConstant(programNode.name), "generatedPrograms");
1756
+ const childScope = { ...scope, instructionNode, programAddressConstant };
1757
+ return mergeFragments([getTypeFragment2(childScope), getFunctionFragment(childScope)], (cs) => cs.join("\n\n"));
1758
+ }
1759
+ function getTypeFragment2(scope) {
1760
+ const customData = scope.customInstructionData.get(scope.instructionNode.name);
1761
+ const instructionParsedType = scope.nameApi.instructionParsedType(scope.instructionNode.name);
1762
+ const instructionDataName = scope.nameApi.instructionDataType(scope.instructionNode.name);
1763
+ const hasData = !!customData || scope.instructionNode.arguments.length > 0;
1764
+ const hasAccounts = scope.instructionNode.accounts.length > 0;
1765
+ const typeParamDeclarations = mergeFragments(
1766
+ [
1767
+ fragment`TProgram extends string = typeof ${scope.programAddressConstant}`,
1768
+ hasAccounts ? fragment`TAccountMetas extends readonly ${use("type AccountMeta", "solanaInstructions")}[] = readonly AccountMeta[]` : void 0
1769
+ ],
1770
+ (cs) => cs.join(", ")
1771
+ );
1772
+ const accounts = mergeFragments(
1773
+ scope.instructionNode.accounts.map((account, i) => {
1774
+ const docs = getDocblockFragment(account.docs ?? [], true);
1775
+ const name = camelCase10(account.name);
1776
+ return fragment`${docs}${name}${account.isOptional ? "?" : ""}: TAccountMetas[${i}]${account.isOptional ? " | undefined" : ""};`;
1693
1777
  }),
1694
- (f) => mergeFragmentImports(f, [dataTypeFragment.imports]),
1695
- (f) => addFragmentImports(f, "generatedPrograms", [programAddressConstant]),
1696
- (f) => addFragmentImports(f, "solanaInstructions", ["type Instruction"]),
1697
- hasAccounts ? (f) => addFragmentImports(f, "solanaInstructions", ["type InstructionWithAccounts", "type AccountMeta"]) : (f) => f,
1698
- hasData ? (f) => addFragmentImports(
1699
- addFragmentImports(f, "solanaInstructions", ["type InstructionWithData"]),
1700
- "solanaCodecsCore",
1701
- ["type ReadonlyUint8Array"]
1702
- ) : (f) => f
1778
+ (cs) => hasAccounts ? `
1779
+ accounts: {
1780
+ ${cs.join("\n")}
1781
+ };` : ""
1782
+ );
1783
+ const dataTypeFragment = customData ? scope.dataArgsManifest.strictType : fragment`${scope.nameApi.dataType(instructionDataName)}`;
1784
+ const data = hasData ? fragment`\ndata: ${dataTypeFragment};` : fragment``;
1785
+ return fragment`export type ${instructionParsedType}<${typeParamDeclarations}> = { programAddress: ${use("type Address", "solanaAddresses")}<TProgram>;${accounts}${data} };`;
1786
+ }
1787
+ function getFunctionFragment(scope) {
1788
+ const customData = scope.customInstructionData.get(scope.instructionNode.name);
1789
+ const instructionParsedType = scope.nameApi.instructionParsedType(scope.instructionNode.name);
1790
+ const instructionParseFunction = scope.nameApi.instructionParseFunction(scope.instructionNode.name);
1791
+ const instructionDataName = scope.nameApi.instructionDataType(scope.instructionNode.name);
1792
+ const decoderFunction = customData ? scope.dataArgsManifest.decoder : fragment`${scope.nameApi.decoderFunction(instructionDataName)}()`;
1793
+ const hasData = !!customData || scope.instructionNode.arguments.length > 0;
1794
+ const hasAccounts = scope.instructionNode.accounts.length > 0;
1795
+ const hasOptionalAccounts = scope.instructionNode.accounts.some((account) => account.isOptional);
1796
+ const minimumNumberOfAccounts = scope.instructionNode.optionalAccountStrategy === "omitted" ? scope.instructionNode.accounts.filter((account) => !account.isOptional).length : scope.instructionNode.accounts.length;
1797
+ const typeParams = ["TProgram", hasAccounts ? "TAccountMetas" : void 0].filter(Boolean).join(", ");
1798
+ const typeParamDeclarations = mergeFragments(
1799
+ [
1800
+ fragment`TProgram extends string`,
1801
+ hasAccounts ? fragment`TAccountMetas extends readonly ${use("type AccountMeta", "solanaInstructions")}[]` : void 0
1802
+ ],
1803
+ (cs) => cs.join(", ")
1804
+ );
1805
+ const instructionType = mergeFragments(
1806
+ [
1807
+ fragment`${use("type Instruction", "solanaInstructions")}<TProgram>`,
1808
+ hasAccounts ? fragment`${use("type InstructionWithAccounts", "solanaInstructions")}<TAccountMetas>` : void 0,
1809
+ hasData ? pipe9(
1810
+ fragment`InstructionWithData<ReadonlyUint8Array>`,
1811
+ (f) => addFragmentImports(f, "solanaInstructions", ["type InstructionWithData"]),
1812
+ (f) => addFragmentImports(f, "solanaCodecsCore", ["type ReadonlyUint8Array"])
1813
+ ) : void 0
1814
+ ],
1815
+ (cs) => cs.join(" & ")
1816
+ );
1817
+ let accountHelpers;
1818
+ if (hasAccounts) {
1819
+ accountHelpers = fragment`if (instruction.accounts.length < ${minimumNumberOfAccounts}) {
1820
+ // TODO: Coded error.
1821
+ throw new Error('Not enough accounts');
1822
+ }
1823
+ let accountIndex = 0;
1824
+ const getNextAccount = () => {
1825
+ const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!;
1826
+ accountIndex += 1;
1827
+ return accountMeta;
1828
+ }`;
1829
+ }
1830
+ if (hasOptionalAccounts && scope.instructionNode.optionalAccountStrategy === "omitted") {
1831
+ accountHelpers = fragment`${accountHelpers}
1832
+ let optionalAccountsRemaining = instruction.accounts.length - ${minimumNumberOfAccounts};
1833
+ const getNextOptionalAccount = () => {
1834
+ if (optionalAccountsRemaining === 0) return undefined;
1835
+ optionalAccountsRemaining -= 1;
1836
+ return getNextAccount();
1837
+ };`;
1838
+ } else if (hasOptionalAccounts) {
1839
+ accountHelpers = fragment`${accountHelpers}
1840
+ const getNextOptionalAccount = () => {
1841
+ const accountMeta = getNextAccount();
1842
+ return accountMeta.address === ${scope.programAddressConstant} ? undefined : accountMeta;
1843
+ };`;
1844
+ }
1845
+ const accounts = mergeFragments(
1846
+ scope.instructionNode.accounts.map(
1847
+ (account) => account.isOptional ? fragment`${camelCase10(account.name)}: getNextOptionalAccount()` : fragment`${camelCase10(account.name)}: getNextAccount()`
1848
+ ),
1849
+ (cs) => hasAccounts ? `, accounts: { ${cs.join(", ")} }` : ""
1703
1850
  );
1851
+ const data = hasData ? fragment`, data: ${decoderFunction}.decode(instruction.data)` : fragment``;
1852
+ return fragment`export function ${instructionParseFunction}<${typeParamDeclarations}>(instruction: ${instructionType}): ${instructionParsedType}<${typeParams}> {
1853
+ ${accountHelpers}
1854
+ return { programAddress: instruction.programAddress${accounts}${data} };
1855
+ }`;
1704
1856
  }
1705
1857
 
1706
1858
  // src/fragments/instructionType.ts
1707
1859
  import { pascalCase as pascalCase6 } from "@codama/nodes";
1708
1860
  import { mapFragmentContent as mapFragmentContent8 } from "@codama/renderers-core";
1709
- import { findProgramNodeFromPath as findProgramNodeFromPath5, getLastNodeFromPath as getLastNodeFromPath14, pipe as pipe17 } from "@codama/visitors-core";
1710
- function getInstructionTypeFragment(scope) {
1861
+ import { findProgramNodeFromPath as findProgramNodeFromPath5, getLastNodeFromPath as getLastNodeFromPath15 } from "@codama/visitors-core";
1862
+ function getInstructionTypeFragment2(scope) {
1711
1863
  const { instructionPath, nameApi, customInstructionData } = scope;
1712
- const instructionNode = getLastNodeFromPath14(instructionPath);
1864
+ const instructionNode = getLastNodeFromPath15(instructionPath);
1713
1865
  const programNode = findProgramNodeFromPath5(instructionPath);
1714
1866
  const hasAccounts = instructionNode.accounts.length > 0;
1715
1867
  const customData = customInstructionData.get(instructionNode.name);
1716
1868
  const hasData = !!customData || instructionNode.arguments.length > 0;
1717
- const instructionDataName = nameApi.instructionDataType(instructionNode.name);
1718
- const programAddressConstant = nameApi.programAddressConstant(programNode.name);
1719
- const dataType = customData ? pascalCase6(customData.importAs) : pascalCase6(instructionDataName);
1720
- const accountTypeParamsFragment = mergeFragments(
1869
+ const instructionType = nameApi.instructionType(instructionNode.name);
1870
+ const programAddressConstant = use(nameApi.programAddressConstant(programNode.name), "generatedPrograms");
1871
+ const accountTypeParams = mergeFragments(
1721
1872
  instructionNode.accounts.map(
1722
1873
  (account) => getInstructionAccountTypeParamFragment({
1723
1874
  ...scope,
@@ -1725,8 +1876,9 @@ function getInstructionTypeFragment(scope) {
1725
1876
  instructionAccountPath: [...instructionPath, account]
1726
1877
  })
1727
1878
  ),
1728
- (renders) => renders.join(", ")
1879
+ (cs) => cs.length > 0 ? `${cs.join(", ")}, ` : ""
1729
1880
  );
1881
+ const data = hasData ? fragment` & ${use("type InstructionWithData", "solanaInstructions")}<${use("type ReadonlyUint8Array", "solanaCodecsCore")}>` : void 0;
1730
1882
  const usesLegacyOptionalAccounts = instructionNode.optionalAccountStrategy === "omitted";
1731
1883
  const accountMetasFragment = mergeFragments(
1732
1884
  instructionNode.accounts.map(
@@ -1740,95 +1892,149 @@ function getInstructionTypeFragment(scope) {
1740
1892
  ),
1741
1893
  (c) => c.join(", ")
1742
1894
  );
1743
- const fragment2 = pipe17(
1744
- fragmentFromTemplate("instructionType.njk", {
1745
- accountMetas: accountMetasFragment.content,
1746
- accountTypeParams: accountTypeParamsFragment.content,
1747
- dataType,
1748
- hasAccounts,
1749
- hasData,
1750
- instruction: instructionNode,
1751
- instructionType: nameApi.instructionType(instructionNode.name),
1752
- programAddressConstant
1753
- }),
1754
- (f) => mergeFragmentImports(f, [accountTypeParamsFragment.imports, accountMetasFragment.imports]),
1755
- (f) => addFragmentImports(f, "generatedPrograms", [programAddressConstant]),
1756
- (f) => addFragmentImports(f, "solanaInstructions", [
1757
- "type AccountMeta",
1758
- "type Instruction",
1759
- "type InstructionWithAccounts",
1760
- ...hasData ? ["type InstructionWithData"] : []
1761
- ])
1895
+ const instructionWithAccounts = use("type InstructionWithAccounts", "solanaInstructions");
1896
+ const accounts = hasAccounts ? fragment` & ${instructionWithAccounts}<[${accountMetasFragment}, ...TRemainingAccounts]>` : fragment` & ${instructionWithAccounts}<TRemainingAccounts>`;
1897
+ return fragment`export type ${instructionType}<TProgram extends string = typeof ${programAddressConstant}, ${accountTypeParams}TRemainingAccounts extends readonly ${use("type AccountMeta", "solanaInstructions")}<string>[] = []> =
1898
+ ${use("type Instruction", "solanaInstructions")}<TProgram>${data}${accounts};`;
1899
+ }
1900
+
1901
+ // src/fragments/instructionPage.ts
1902
+ function getInstructionPageFragment(scope) {
1903
+ const node = getLastNodeFromPath16(scope.instructionPath);
1904
+ if (!findProgramNodeFromPath6(scope.instructionPath)) {
1905
+ throw new Error("Instruction must be visited inside a program.");
1906
+ }
1907
+ const childScope = {
1908
+ ...scope,
1909
+ dataArgsManifest: visit5(node, scope.typeManifestVisitor),
1910
+ extraArgsManifest: visit5(
1911
+ definedTypeNode2({
1912
+ name: scope.nameApi.instructionExtraType(node.name),
1913
+ type: structTypeNodeFromInstructionArgumentNodes3(node.extraArguments ?? [])
1914
+ }),
1915
+ scope.typeManifestVisitor
1916
+ ),
1917
+ renamedArgs: getRenamedArgsMap(node)
1918
+ };
1919
+ return mergeFragments(
1920
+ [
1921
+ getDiscriminatorConstantsFragment({
1922
+ ...childScope,
1923
+ discriminatorNodes: node.discriminators ?? [],
1924
+ fields: node.arguments,
1925
+ prefix: node.name
1926
+ }),
1927
+ getInstructionTypeFragment2(childScope),
1928
+ getInstructionDataFragment(childScope),
1929
+ getInstructionExtraArgsFragment(childScope),
1930
+ getInstructionFunctionFragment({ ...childScope, useAsync: true }),
1931
+ getInstructionFunctionFragment({ ...childScope, useAsync: false }),
1932
+ getInstructionParseFunctionFragment(childScope)
1933
+ ],
1934
+ (cs) => cs.join("\n\n")
1935
+ );
1936
+ }
1937
+ function getRenamedArgsMap(instruction) {
1938
+ const argNames = [
1939
+ ...instruction.arguments.map((a) => a.name),
1940
+ ...(instruction.extraArguments ?? []).map((a) => a.name)
1941
+ ];
1942
+ const duplicateArgs = argNames.filter((e, i, a) => a.indexOf(e) !== i);
1943
+ if (duplicateArgs.length > 0) {
1944
+ throw new Error(`Duplicate args found: [${duplicateArgs.join(", ")}] in instruction [${instruction.name}].`);
1945
+ }
1946
+ const allNames = [...instruction.accounts.map((account) => account.name), ...argNames];
1947
+ const duplicates = allNames.filter((e, i, a) => a.indexOf(e) !== i);
1948
+ if (duplicates.length === 0) return /* @__PURE__ */ new Map();
1949
+ logWarn(
1950
+ `[JavaScript] Accounts and args of instruction [${instruction.name}] have the following conflicting attributes [${duplicates.join(", ")}]. Thus, the arguments have been renamed to avoid conflicts in the input type.`
1762
1951
  );
1763
- return fragment2;
1952
+ return new Map(duplicates.map((name) => [camelCase11(name), camelCase11(`${name}Arg`)]));
1764
1953
  }
1765
1954
 
1766
1955
  // src/fragments/pdaFunction.ts
1767
- import { isNode as isNode13, isNodeFilter as isNodeFilter5 } from "@codama/nodes";
1768
- import { findProgramNodeFromPath as findProgramNodeFromPath6, getLastNodeFromPath as getLastNodeFromPath15, pipe as pipe18, visit as visit4 } from "@codama/visitors-core";
1956
+ import { camelCase as camelCase12, isNode as isNode13, isNodeFilter as isNodeFilter5 } from "@codama/nodes";
1957
+ import { findProgramNodeFromPath as findProgramNodeFromPath7, getLastNodeFromPath as getLastNodeFromPath17, visit as visit6 } from "@codama/visitors-core";
1769
1958
  function getPdaFunctionFragment(scope) {
1770
- const { pdaPath, typeManifestVisitor, nameApi } = scope;
1771
- const pdaNode = getLastNodeFromPath15(pdaPath);
1772
- const programNode = findProgramNodeFromPath6(pdaPath);
1773
- const imports = new ImportMap();
1774
- const seeds = pdaNode.seeds.map((seed) => {
1959
+ const pdaNode = getLastNodeFromPath17(scope.pdaPath);
1960
+ const seeds = parsePdaSeedNodes(pdaNode.seeds, scope);
1961
+ return mergeFragments(
1962
+ [getSeedInputTypeFragment(seeds, scope), getFunctionFragment2(seeds, scope)],
1963
+ (cs) => cs.join("\n\n")
1964
+ );
1965
+ }
1966
+ function getSeedInputTypeFragment(seeds, scope) {
1967
+ const variableSeeds = seeds.filter(isNodeFilter5("variablePdaSeedNode"));
1968
+ if (variableSeeds.length === 0) return;
1969
+ const pdaNode = getLastNodeFromPath17(scope.pdaPath);
1970
+ const seedTypeName = scope.nameApi.pdaSeedsType(pdaNode.name);
1971
+ const seedAttributes = mergeFragments(
1972
+ variableSeeds.map((seed) => seed.inputAttribute),
1973
+ (cs) => cs.join("\n")
1974
+ );
1975
+ return fragment`export type ${seedTypeName} = {\n${seedAttributes}\n};`;
1976
+ }
1977
+ function getFunctionFragment2(seeds, scope) {
1978
+ const pdaNode = getLastNodeFromPath17(scope.pdaPath);
1979
+ const programNode = findProgramNodeFromPath7(scope.pdaPath);
1980
+ const addressType = use("type Address", "solanaAddresses");
1981
+ const pdaType = use("type ProgramDerivedAddress", "solanaAddresses");
1982
+ const getPdaFunction = use("getProgramDerivedAddress", "solanaAddresses");
1983
+ const seedTypeName = scope.nameApi.pdaSeedsType(pdaNode.name);
1984
+ const findPdaFunction = scope.nameApi.pdaFindFunction(pdaNode.name);
1985
+ const docs = getDocblockFragment(pdaNode.docs ?? [], true);
1986
+ const hasVariableSeeds = seeds.filter(isNodeFilter5("variablePdaSeedNode")).length > 0;
1987
+ const seedArgument = hasVariableSeeds ? `seeds: ${seedTypeName}, ` : "";
1988
+ const programAddress = pdaNode.programId ?? programNode.publicKey;
1989
+ const encodedSeeds = mergeFragments(
1990
+ seeds.map((s) => s.encodedValue),
1991
+ (cs) => cs.join(", ")
1992
+ );
1993
+ return fragment`${docs}export async function ${findPdaFunction}(${seedArgument}config: { programAddress?: ${addressType} | undefined } = {}): Promise<${pdaType}> {
1994
+ const { programAddress = '${programAddress}' as ${addressType}<'${programAddress}'> } = config;
1995
+ return await ${getPdaFunction}({ programAddress, seeds: [${encodedSeeds}]});
1996
+ }`;
1997
+ }
1998
+ function parsePdaSeedNodes(seeds, scope) {
1999
+ return seeds.map((seed) => {
1775
2000
  if (isNode13(seed, "variablePdaSeedNode")) {
1776
- const seedManifest2 = visit4(seed.type, typeManifestVisitor);
1777
- imports.mergeWith(seedManifest2.looseType, seedManifest2.encoder);
1778
- return { ...seed, typeManifest: seedManifest2 };
2001
+ const name = camelCase12(seed.name);
2002
+ const docs = getDocblockFragment(seed.docs ?? [], true);
2003
+ const { encoder: encoder2, looseType } = visit6(seed.type, scope.typeManifestVisitor);
2004
+ return {
2005
+ ...seed,
2006
+ encodedValue: fragment`${encoder2}.encode(seeds.${name})`,
2007
+ inputAttribute: fragment`${docs}${name}: ${looseType};`
2008
+ };
1779
2009
  }
1780
2010
  if (isNode13(seed.value, "programIdValueNode")) {
1781
- imports.add("solanaAddresses", "getAddressEncoder");
1782
- return seed;
2011
+ const addressEncoder = use("getAddressEncoder", "solanaAddresses");
2012
+ return { ...seed, encodedValue: fragment`${addressEncoder}().encode(programAddress)` };
1783
2013
  }
1784
- const seedManifest = visit4(seed.type, typeManifestVisitor);
1785
- imports.mergeWith(seedManifest.encoder);
1786
- const valueManifest = visit4(seed.value, typeManifestVisitor).value;
1787
- imports.mergeWith(valueManifest.imports);
1788
- return { ...seed, typeManifest: seedManifest, valueManifest };
2014
+ const { encoder } = visit6(seed.type, scope.typeManifestVisitor);
2015
+ const { value } = visit6(seed.value, scope.typeManifestVisitor);
2016
+ return { ...seed, encodedValue: fragment`${encoder}.encode(${value})` };
1789
2017
  });
1790
- const hasVariableSeeds = pdaNode.seeds.filter(isNodeFilter5("variablePdaSeedNode")).length > 0;
1791
- return pipe18(
1792
- fragmentFromTemplate("pdaFunction.njk", {
1793
- findPdaFunction: nameApi.pdaFindFunction(pdaNode.name),
1794
- hasVariableSeeds,
1795
- pdaDocs: pdaNode.docs,
1796
- pdaSeedsType: nameApi.pdaSeedsType(pdaNode.name),
1797
- programAddress: pdaNode.programId ?? programNode.publicKey,
1798
- seeds
1799
- }),
1800
- (f) => mergeFragmentImports(f, [imports]),
1801
- (f) => addFragmentImports(f, "solanaAddresses", [
1802
- "type Address",
1803
- "getProgramDerivedAddress",
1804
- "type ProgramDerivedAddress"
1805
- ])
1806
- );
1807
2018
  }
1808
2019
 
1809
- // src/fragments/program.ts
1810
- import { pipe as pipe19 } from "@codama/visitors-core";
1811
- function getProgramFragment(scope) {
1812
- const { programNode, nameApi } = scope;
1813
- return pipe19(
1814
- fragmentFromTemplate("program.njk", {
1815
- program: programNode,
1816
- programAddressConstant: nameApi.programAddressConstant(programNode.name)
1817
- }),
1818
- (f) => addFragmentImports(f, "solanaAddresses", ["type Address"])
1819
- );
2020
+ // src/fragments/pdaPage.ts
2021
+ import { findProgramNodeFromPath as findProgramNodeFromPath8 } from "@codama/visitors-core";
2022
+ function getPdaPageFragment(scope) {
2023
+ if (!findProgramNodeFromPath8(scope.pdaPath)) {
2024
+ throw new Error("PDA must be visited inside a program.");
2025
+ }
2026
+ return getPdaFunctionFragment(scope);
1820
2027
  }
1821
2028
 
1822
2029
  // src/fragments/programAccounts.ts
1823
- import { resolveNestedTypeNode as resolveNestedTypeNode2 } from "@codama/nodes";
2030
+ import { resolveNestedTypeNode as resolveNestedTypeNode3 } from "@codama/nodes";
1824
2031
  import { mapFragmentContent as mapFragmentContent9 } from "@codama/renderers-core";
1825
- import { pipe as pipe20 } from "@codama/visitors-core";
2032
+ import { pipe as pipe10 } from "@codama/visitors-core";
1826
2033
  function getProgramAccountsFragment(scope) {
1827
- if (scope.programNode.accounts.length === 0) return fragment("");
2034
+ if (scope.programNode.accounts.length === 0) return;
1828
2035
  return mergeFragments(
1829
2036
  [getProgramAccountsEnumFragment(scope), getProgramAccountsIdentifierFunctionFragment(scope)],
1830
- (c) => `${c.join("\n\n")}
1831
- `
2037
+ (c) => c.join("\n\n")
1832
2038
  );
1833
2039
  }
1834
2040
  function getProgramAccountsEnumFragment(scope) {
@@ -1837,7 +2043,7 @@ function getProgramAccountsEnumFragment(scope) {
1837
2043
  const programAccountsEnumVariants = programNode.accounts.map(
1838
2044
  (account) => nameApi.programAccountsEnumVariant(account.name)
1839
2045
  );
1840
- return fragment(`export enum ${programAccountsEnum} { ${programAccountsEnumVariants.join(", ")} }`);
2046
+ return fragment`export enum ${programAccountsEnum} { ${programAccountsEnumVariants.join(", ")} }`;
1841
2047
  }
1842
2048
  function getProgramAccountsIdentifierFunctionFragment(scope) {
1843
2049
  const { programNode, nameApi } = scope;
@@ -1845,10 +2051,10 @@ function getProgramAccountsIdentifierFunctionFragment(scope) {
1845
2051
  (account) => (account.discriminators ?? []).length > 0
1846
2052
  );
1847
2053
  const hasAccountDiscriminators = accountsWithDiscriminators.length > 0;
1848
- if (!hasAccountDiscriminators) return fragment("");
2054
+ if (!hasAccountDiscriminators) return;
1849
2055
  const programAccountsEnum = nameApi.programAccountsEnum(programNode.name);
1850
2056
  const programAccountsIdentifierFunction = nameApi.programAccountsIdentifierFunction(programNode.name);
1851
- return pipe20(
2057
+ return pipe10(
1852
2058
  mergeFragments(
1853
2059
  accountsWithDiscriminators.map((account) => {
1854
2060
  const variant = nameApi.programAccountsEnumVariant(account.name);
@@ -1857,7 +2063,7 @@ function getProgramAccountsIdentifierFunctionFragment(scope) {
1857
2063
  dataName: "data",
1858
2064
  discriminators: account.discriminators ?? [],
1859
2065
  ifTrue: `return ${programAccountsEnum}.${variant};`,
1860
- struct: resolveNestedTypeNode2(account.data)
2066
+ struct: resolveNestedTypeNode3(account.data)
1861
2067
  });
1862
2068
  }),
1863
2069
  (c) => c.join("\n")
@@ -1874,25 +2080,13 @@ throw new Error("The provided account could not be identified as a ${programNode
1874
2080
  );
1875
2081
  }
1876
2082
 
1877
- // src/fragments/programErrors.ts
1878
- import { pipe as pipe21 } from "@codama/visitors-core";
1879
- function getProgramErrorsFragment(scope) {
2083
+ // src/fragments/programConstant.ts
2084
+ import { pipe as pipe11 } from "@codama/visitors-core";
2085
+ function getProgramConstantFragment(scope) {
1880
2086
  const { programNode, nameApi } = scope;
1881
2087
  const programAddressConstant = nameApi.programAddressConstant(programNode.name);
1882
- return pipe21(
1883
- fragmentFromTemplate("programErrors.njk", {
1884
- errors: programNode.errors,
1885
- escapeProgramErrorMessage: (message) => message.replace(/`/g, "\\`"),
1886
- getProgramErrorConstant: (name) => nameApi.programErrorConstantPrefix(programNode.name) + nameApi.programErrorConstant(name),
1887
- programAddressConstant,
1888
- programErrorMessagesMap: nameApi.programErrorMessagesMap(programNode.name),
1889
- programErrorUnion: nameApi.programErrorUnion(programNode.name),
1890
- programGetErrorMessageFunction: nameApi.programGetErrorMessageFunction(programNode.name),
1891
- programIsErrorFunction: nameApi.programIsErrorFunction(programNode.name)
1892
- }),
1893
- (f) => addFragmentImports(f, "generatedPrograms", [programAddressConstant]),
1894
- (f) => addFragmentImports(f, "solanaPrograms", ["isProgramError"]),
1895
- (f) => addFragmentImports(f, "solanaErrors", ["type SolanaError", "type SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM"]),
2088
+ return pipe11(
2089
+ fragment`export const ${programAddressConstant} = '${programNode.publicKey}' as Address<'${programNode.publicKey}'>;`,
1896
2090
  (f) => addFragmentImports(f, "solanaAddresses", ["type Address"])
1897
2091
  );
1898
2092
  }
@@ -1900,12 +2094,12 @@ function getProgramErrorsFragment(scope) {
1900
2094
  // src/fragments/programInstructions.ts
1901
2095
  import {
1902
2096
  getAllInstructionsWithSubs,
1903
- structTypeNodeFromInstructionArgumentNodes as structTypeNodeFromInstructionArgumentNodes3
2097
+ structTypeNodeFromInstructionArgumentNodes as structTypeNodeFromInstructionArgumentNodes4
1904
2098
  } from "@codama/nodes";
1905
2099
  import { mapFragmentContent as mapFragmentContent10 } from "@codama/renderers-core";
1906
- import { pipe as pipe22 } from "@codama/visitors-core";
2100
+ import { pipe as pipe12 } from "@codama/visitors-core";
1907
2101
  function getProgramInstructionsFragment(scope) {
1908
- if (scope.programNode.instructions.length === 0) return fragment("");
2102
+ if (scope.programNode.instructions.length === 0) return;
1909
2103
  const allInstructions = getAllInstructionsWithSubs(scope.programNode, {
1910
2104
  leavesOnly: !scope.renderParentInstructions,
1911
2105
  subInstructionsFirst: true
@@ -1917,8 +2111,7 @@ function getProgramInstructionsFragment(scope) {
1917
2111
  getProgramInstructionsIdentifierFunctionFragment(scopeWithInstructions),
1918
2112
  getProgramInstructionsParsedUnionTypeFragment(scopeWithInstructions)
1919
2113
  ],
1920
- (c) => `${c.join("\n\n")}
1921
- `
2114
+ (c) => c.join("\n\n")
1922
2115
  );
1923
2116
  }
1924
2117
  function getProgramInstructionsEnumFragment(scope) {
@@ -1927,9 +2120,7 @@ function getProgramInstructionsEnumFragment(scope) {
1927
2120
  const programInstructionsEnumVariants = allInstructions.map(
1928
2121
  (instruction) => nameApi.programInstructionsEnumVariant(instruction.name)
1929
2122
  );
1930
- return fragment(
1931
- `export enum ${programInstructionsEnum} { ${programInstructionsEnumVariants.join(", ")} }`
1932
- );
2123
+ return fragment`export enum ${programInstructionsEnum} { ${programInstructionsEnumVariants.join(", ")} }`;
1933
2124
  }
1934
2125
  function getProgramInstructionsIdentifierFunctionFragment(scope) {
1935
2126
  const { programNode, nameApi, allInstructions } = scope;
@@ -1937,7 +2128,7 @@ function getProgramInstructionsIdentifierFunctionFragment(scope) {
1937
2128
  (instruction) => (instruction.discriminators ?? []).length > 0
1938
2129
  );
1939
2130
  const hasInstructionDiscriminators = instructionsWithDiscriminators.length > 0;
1940
- if (!hasInstructionDiscriminators) return fragment("");
2131
+ if (!hasInstructionDiscriminators) return;
1941
2132
  const programInstructionsEnum = nameApi.programInstructionsEnum(programNode.name);
1942
2133
  const programInstructionsIdentifierFunction = nameApi.programInstructionsIdentifierFunction(programNode.name);
1943
2134
  const discriminatorsFragment = mergeFragments(
@@ -1948,12 +2139,12 @@ function getProgramInstructionsIdentifierFunctionFragment(scope) {
1948
2139
  dataName: "data",
1949
2140
  discriminators: instruction.discriminators ?? [],
1950
2141
  ifTrue: `return ${programInstructionsEnum}.${variant};`,
1951
- struct: structTypeNodeFromInstructionArgumentNodes3(instruction.arguments)
2142
+ struct: structTypeNodeFromInstructionArgumentNodes4(instruction.arguments)
1952
2143
  });
1953
2144
  }),
1954
2145
  (c) => c.join("\n")
1955
2146
  );
1956
- return pipe22(
2147
+ return pipe12(
1957
2148
  discriminatorsFragment,
1958
2149
  (f) => mapFragmentContent10(
1959
2150
  f,
@@ -1973,78 +2164,256 @@ function getProgramInstructionsParsedUnionTypeFragment(scope) {
1973
2164
  const programInstructionsEnum = nameApi.programInstructionsEnum(programNode.name);
1974
2165
  const typeVariants = allInstructions.map((instruction) => {
1975
2166
  const instructionEnumVariant = nameApi.programInstructionsEnumVariant(instruction.name);
1976
- const parsedInstructionType = nameApi.instructionParsedType(instruction.name);
1977
- return pipe22(
1978
- fragment(
1979
- `| { instructionType: ${programInstructionsEnum}.${instructionEnumVariant} } & ${parsedInstructionType}<TProgram>`
1980
- ),
1981
- (f) => addFragmentImports(f, "generatedInstructions", [`type ${parsedInstructionType}`])
2167
+ const parsedInstructionType = use(
2168
+ `type ${nameApi.instructionParsedType(instruction.name)}`,
2169
+ "generatedInstructions"
1982
2170
  );
2171
+ return fragment`| { instructionType: ${programInstructionsEnum}.${instructionEnumVariant} } & ${parsedInstructionType}<TProgram>`;
1983
2172
  });
1984
2173
  return mergeFragments(
1985
2174
  [
1986
- fragment(`export type ${programInstructionsType}<TProgram extends string = '${programAddress}'> =`),
1987
- ...typeVariants
2175
+ fragment`export type ${programInstructionsType}<TProgram extends string = '${programAddress}'> =`,
2176
+ ...typeVariants
2177
+ ],
2178
+ (c) => c.join("\n")
2179
+ );
2180
+ }
2181
+
2182
+ // src/fragments/programPage.ts
2183
+ function getProgramPageFragment(scope) {
2184
+ return mergeFragments(
2185
+ [getProgramConstantFragment(scope), getProgramAccountsFragment(scope), getProgramInstructionsFragment(scope)],
2186
+ (cs) => cs.join("\n\n")
2187
+ );
2188
+ }
2189
+
2190
+ // src/fragments/rootIndexPage.ts
2191
+ function getRootIndexPageFragment(scope) {
2192
+ const hasAnythingToExport = scope.programsToExport.length > 0 || scope.accountsToExport.length > 0 || scope.instructionsToExport.length > 0 || scope.definedTypesToExport.length > 0;
2193
+ if (!hasAnythingToExport) {
2194
+ return fragment`export default {};`;
2195
+ }
2196
+ const programsWithErrorsToExport = scope.programsToExport.filter((p) => p.errors.length > 0);
2197
+ return mergeFragments(
2198
+ [
2199
+ scope.accountsToExport.length > 0 ? getExportAllFragment("./accounts") : void 0,
2200
+ programsWithErrorsToExport.length > 0 ? getExportAllFragment("./errors") : void 0,
2201
+ scope.instructionsToExport.length > 0 ? getExportAllFragment("./instructions") : void 0,
2202
+ scope.pdasToExport.length > 0 ? getExportAllFragment("./pdas") : void 0,
2203
+ scope.programsToExport.length > 0 ? getExportAllFragment("./programs") : void 0,
2204
+ scope.definedTypesToExport.length > 0 ? getExportAllFragment("./types") : void 0
1988
2205
  ],
1989
- (c) => c.join("\n")
2206
+ (cs) => cs.join("\n")
2207
+ );
2208
+ }
2209
+
2210
+ // src/fragments/sharedPage.ts
2211
+ import { pipe as pipe13 } from "@codama/visitors-core";
2212
+ function getSharedPageFragment() {
2213
+ const sharedPage = fragment`/**
2214
+ * Asserts that the given value is not null or undefined.
2215
+ * @internal
2216
+ */
2217
+ export function expectSome<T>(value: T | null | undefined): T {
2218
+ if (value === null || value === undefined) {
2219
+ throw new Error('Expected a value but received null or undefined.');
2220
+ }
2221
+ return value;
2222
+ }
2223
+
2224
+ /**
2225
+ * Asserts that the given value is a PublicKey.
2226
+ * @internal
2227
+ */
2228
+ export function expectAddress<T extends string = string>(
2229
+ value: Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null | undefined
2230
+ ): Address<T> {
2231
+ if (!value) {
2232
+ throw new Error('Expected a Address.');
2233
+ }
2234
+ if (typeof value === 'object' && "address" in value) {
2235
+ return value.address;
2236
+ }
2237
+ if (Array.isArray(value)) {
2238
+ return value[0] as Address<T>;
2239
+ }
2240
+ return value as Address<T>;
2241
+ }
2242
+
2243
+ /**
2244
+ * Asserts that the given value is a PDA.
2245
+ * @internal
2246
+ */
2247
+ export function expectProgramDerivedAddress<T extends string = string>(
2248
+ value: Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null | undefined
2249
+ ): ProgramDerivedAddress<T> {
2250
+ if (!value || !Array.isArray(value) || !isProgramDerivedAddress(value)) {
2251
+ throw new Error('Expected a ProgramDerivedAddress.');
2252
+ }
2253
+ return value;
2254
+ }
2255
+
2256
+ /**
2257
+ * Asserts that the given value is a TransactionSigner.
2258
+ * @internal
2259
+ */
2260
+ export function expectTransactionSigner<T extends string = string>(
2261
+ value: Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null | undefined
2262
+ ): TransactionSigner<T> {
2263
+ if (!value || !isTransactionSigner(value)) {
2264
+ throw new Error('Expected a TransactionSigner.');
2265
+ }
2266
+ return value;
2267
+ }
2268
+
2269
+ /**
2270
+ * Defines an instruction account to resolve.
2271
+ * @internal
2272
+ */
2273
+ export type ResolvedAccount<T extends string = string, U extends Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null = Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null> = {
2274
+ isWritable: boolean;
2275
+ value: U;
2276
+ };
2277
+
2278
+ /**
2279
+ * Defines an instruction that stores additional bytes on-chain.
2280
+ * @internal
2281
+ */
2282
+ export type InstructionWithByteDelta = {
2283
+ byteDelta: number;
2284
+ };
2285
+
2286
+ /**
2287
+ * Get account metas and signers from resolved accounts.
2288
+ * @internal
2289
+ */
2290
+ export function getAccountMetaFactory(
2291
+ programAddress: Address,
2292
+ optionalAccountStrategy: 'omitted' | 'programId',
2293
+ ) {
2294
+ return (account: ResolvedAccount): AccountMeta | AccountSignerMeta | undefined => {
2295
+ if (!account.value) {
2296
+ if (optionalAccountStrategy === 'omitted') return;
2297
+ return Object.freeze({ address: programAddress, role: AccountRole.READONLY });
2298
+ }
2299
+
2300
+ const writableRole = account.isWritable ? AccountRole.WRITABLE : AccountRole.READONLY;
2301
+ return Object.freeze({
2302
+ address: expectAddress(account.value),
2303
+ role: isTransactionSigner(account.value) ? upgradeRoleToSigner(writableRole) : writableRole,
2304
+ ...(isTransactionSigner(account.value) ? { signer: account.value } : {})
2305
+ });
2306
+ };
2307
+ }
2308
+
2309
+ export function isTransactionSigner<TAddress extends string = string>(value: Address<TAddress> | ProgramDerivedAddress<TAddress> | TransactionSigner<TAddress>): value is TransactionSigner<TAddress> {
2310
+ return !!value && typeof value === 'object' && 'address' in value && kitIsTransactionSigner(value);
2311
+ }`;
2312
+ return pipe13(
2313
+ sharedPage,
2314
+ (f) => addFragmentImports(f, "solanaAddresses", [
2315
+ "type Address",
2316
+ "isProgramDerivedAddress",
2317
+ "type ProgramDerivedAddress"
2318
+ ]),
2319
+ (f) => addFragmentImports(f, "solanaInstructions", ["AccountRole", "type AccountMeta", "upgradeRoleToSigner"]),
2320
+ (f) => addFragmentImports(f, "solanaSigners", [
2321
+ "type AccountSignerMeta",
2322
+ "isTransactionSigner as kitIsTransactionSigner",
2323
+ "type TransactionSigner"
2324
+ ])
1990
2325
  );
1991
2326
  }
1992
2327
 
1993
2328
  // src/fragments/typeDiscriminatedUnionHelpers.ts
1994
2329
  import { isDataEnum as isDataEnum3, isNode as isNode14 } from "@codama/nodes";
1995
- import { pipe as pipe23 } from "@codama/visitors-core";
1996
2330
  function getTypeDiscriminatedUnionHelpersFragment(scope) {
1997
2331
  const { name, typeNode, nameApi } = scope;
1998
2332
  const isDiscriminatedUnion = isNode14(typeNode, "enumTypeNode") && isDataEnum3(typeNode);
1999
- if (!isDiscriminatedUnion) {
2000
- return fragment("");
2001
- }
2002
- return pipe23(
2003
- fragmentFromTemplate("typeDiscriminatedUnionHelpers.njk", {
2004
- discriminatedUnionDiscriminator: nameApi.discriminatedUnionDiscriminator(name),
2005
- discriminatedUnionFunction: nameApi.discriminatedUnionFunction(name),
2006
- getVariant: (variant) => nameApi.discriminatedUnionVariant(variant),
2007
- isDiscriminatedUnionFunction: nameApi.isDiscriminatedUnionFunction(name),
2008
- looseName: nameApi.dataArgsType(name),
2009
- strictName: nameApi.dataType(name),
2010
- typeNode
2333
+ if (!isDiscriminatedUnion) return;
2334
+ const functionName = nameApi.discriminatedUnionFunction(name);
2335
+ const isDiscriminatedUnionFunctionName = nameApi.isDiscriminatedUnionFunction(name);
2336
+ const discriminatorName = nameApi.discriminatedUnionDiscriminator(name);
2337
+ const strictName = nameApi.dataType(name);
2338
+ const looseName = nameApi.dataArgsType(name);
2339
+ const getVariantContentType = use("type GetDiscriminatedUnionVariantContent", "solanaCodecsDataStructures");
2340
+ const getVariantType = use("type GetDiscriminatedUnionVariant", "solanaCodecsDataStructures");
2341
+ const variantSignatures = mergeFragments(
2342
+ typeNode.variants.map((variant) => {
2343
+ const variantName = nameApi.discriminatedUnionVariant(variant.name);
2344
+ if (isNode14(variant, "enumStructVariantTypeNode")) {
2345
+ return fragment`export function ${functionName}(kind: '${variantName}', data: ${getVariantContentType}<${looseName}, '${discriminatorName}', '${variantName}'>): ${getVariantType}<${looseName}, '${discriminatorName}', '${variantName}'>;`;
2346
+ }
2347
+ if (isNode14(variant, "enumTupleVariantTypeNode")) {
2348
+ return fragment`export function ${functionName}(kind: '${variantName}', data: ${getVariantContentType}<${looseName}, '${discriminatorName}', '${variantName}'>['fields']): ${getVariantType}<${looseName}, '${discriminatorName}', '${variantName}'>;`;
2349
+ }
2350
+ return fragment`export function ${functionName}(kind: '${variantName}'): ${getVariantType}<${looseName}, '${discriminatorName}', '${variantName}'>;`;
2011
2351
  }),
2012
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", [
2013
- "type GetDiscriminatedUnionVariantContent",
2014
- "type GetDiscriminatedUnionVariant"
2352
+ (cs) => cs.length > 0 ? `${cs.join("\n")}
2353
+ ` : ""
2354
+ );
2355
+ return fragment`// Data Enum Helpers.
2356
+ ${variantSignatures}export function ${functionName}<K extends ${looseName}['${discriminatorName}'], Data>(kind: K, data?: Data) {
2357
+ return Array.isArray(data) ? { ${discriminatorName}: kind, fields: data } : { ${discriminatorName}: kind, ...(data ?? {}) };
2358
+ }
2359
+
2360
+ export function ${isDiscriminatedUnionFunctionName}<K extends ${strictName}['${discriminatorName}']>(kind: K, value: ${strictName}): value is ${strictName} & { ${discriminatorName}: K } {
2361
+ return value.${discriminatorName} === kind;
2362
+ };
2363
+ `;
2364
+ }
2365
+
2366
+ // src/fragments/typePage.ts
2367
+ import { pipe as pipe14, visit as visit7 } from "@codama/visitors-core";
2368
+ function getTypePageFragment(scope) {
2369
+ const node = scope.node;
2370
+ const manifest = visit7(node, scope.typeManifestVisitor);
2371
+ return pipe14(
2372
+ mergeFragments(
2373
+ [
2374
+ getTypeWithCodecFragment({ ...scope, manifest, name: node.name, node: node.type, typeDocs: node.docs }),
2375
+ getTypeDiscriminatedUnionHelpersFragment({ ...scope, name: node.name, typeNode: node.type })
2376
+ ],
2377
+ (cs) => cs.join("\n\n")
2378
+ ),
2379
+ (f) => removeFragmentImports(f, "generatedTypes", [
2380
+ scope.nameApi.dataType(node.name),
2381
+ scope.nameApi.dataArgsType(node.name),
2382
+ scope.nameApi.encoderFunction(node.name),
2383
+ scope.nameApi.decoderFunction(node.name),
2384
+ scope.nameApi.codecFunction(node.name)
2015
2385
  ])
2016
2386
  );
2017
2387
  }
2018
2388
 
2019
- // src/getTypeManifestVisitor.ts
2389
+ // src/visitors/getTypeManifestVisitor.ts
2020
2390
  import {
2021
- camelCase as camelCase10,
2391
+ camelCase as camelCase13,
2022
2392
  isNode as isNode15,
2023
2393
  isNodeFilter as isNodeFilter6,
2024
2394
  isScalarEnum,
2025
- parseDocs as parseDocs2,
2026
2395
  REGISTERED_TYPE_NODE_KINDS,
2027
2396
  REGISTERED_VALUE_NODE_KINDS,
2028
- resolveNestedTypeNode as resolveNestedTypeNode3,
2397
+ resolveNestedTypeNode as resolveNestedTypeNode4,
2029
2398
  structFieldTypeNode,
2030
2399
  structTypeNode,
2031
- structTypeNodeFromInstructionArgumentNodes as structTypeNodeFromInstructionArgumentNodes4
2400
+ structTypeNodeFromInstructionArgumentNodes as structTypeNodeFromInstructionArgumentNodes5
2032
2401
  } from "@codama/nodes";
2033
2402
  import { mapFragmentContent as mapFragmentContent11, setFragmentContent as setFragmentContent2 } from "@codama/renderers-core";
2034
2403
  import {
2035
2404
  extendVisitor,
2036
2405
  findLastNodeFromPath,
2037
2406
  NodeStack,
2038
- pipe as pipe24,
2407
+ pipe as pipe15,
2039
2408
  recordNodeStackVisitor,
2040
2409
  staticVisitor,
2041
- visit as visit5
2410
+ visit as visit8
2042
2411
  } from "@codama/visitors-core";
2043
2412
  function getTypeManifestVisitor(input) {
2044
2413
  const { nameApi, linkables, nonScalarEnums, customAccountData, customInstructionData, getImportFrom } = input;
2045
2414
  const stack = input.stack ?? new NodeStack();
2046
2415
  let parentName = null;
2047
- return pipe24(
2416
+ return pipe15(
2048
2417
  staticVisitor(() => typeManifest(), {
2049
2418
  keys: [
2050
2419
  ...REGISTERED_TYPE_NODE_KINDS,
@@ -2062,117 +2431,81 @@ function getTypeManifestVisitor(input) {
2062
2431
  strict: nameApi.dataType(account.name)
2063
2432
  };
2064
2433
  const link = customAccountData.get(account.name)?.linkNode;
2065
- const manifest = link ? visit5(link, self) : visit5(account.data, self);
2434
+ const manifest = link ? visit8(link, self) : visit8(account.data, self);
2066
2435
  parentName = null;
2067
2436
  return manifest;
2068
2437
  },
2069
2438
  visitAmountType(amountType, { self }) {
2070
- return visit5(amountType.number, self);
2439
+ return visit8(amountType.number, self);
2071
2440
  },
2072
2441
  visitArrayType(arrayType, { self }) {
2073
- const childManifest = visit5(arrayType.item, self);
2442
+ const childManifest = visit8(arrayType.item, self);
2074
2443
  const sizeManifest = getArrayLikeSizeOption(arrayType.count, self);
2075
- const encoderOptions = sizeManifest.encoder.content ? `, { ${sizeManifest.encoder.content} }` : "";
2076
- const decoderOptions = sizeManifest.decoder.content ? `, { ${sizeManifest.decoder.content} }` : "";
2444
+ const encoderOptions = sizeManifest.encoder ? fragment`, { ${sizeManifest.encoder} }` : "";
2445
+ const decoderOptions = sizeManifest.decoder ? fragment`, { ${sizeManifest.decoder} }` : "";
2077
2446
  return typeManifest({
2078
2447
  ...childManifest,
2079
- decoder: pipe24(
2080
- childManifest.decoder,
2081
- (f) => mapFragmentContent11(f, (c) => `getArrayDecoder(${c + decoderOptions})`),
2082
- (f) => mergeFragmentImports(f, [sizeManifest.decoder.imports]),
2083
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getArrayDecoder"])
2084
- ),
2085
- encoder: pipe24(
2086
- childManifest.encoder,
2087
- (f) => mapFragmentContent11(f, (c) => `getArrayEncoder(${c + encoderOptions})`),
2088
- (f) => mergeFragmentImports(f, [sizeManifest.encoder.imports]),
2089
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getArrayEncoder"])
2090
- ),
2091
- looseType: mapFragmentContent11(childManifest.looseType, (c) => `Array<${c}>`),
2092
- strictType: mapFragmentContent11(childManifest.strictType, (c) => `Array<${c}>`)
2448
+ decoder: fragment`${use("getArrayDecoder", "solanaCodecsDataStructures")}(${childManifest.decoder}${decoderOptions})`,
2449
+ encoder: fragment`${use("getArrayEncoder", "solanaCodecsDataStructures")}(${childManifest.encoder}${encoderOptions})`,
2450
+ looseType: fragment`Array<${childManifest.looseType}>`,
2451
+ strictType: fragment`Array<${childManifest.strictType}>`
2093
2452
  });
2094
2453
  },
2095
2454
  visitArrayValue(node, { self }) {
2096
2455
  return mergeTypeManifests(
2097
- node.items.map((v) => visit5(v, self)),
2456
+ node.items.map((v) => visit8(v, self)),
2098
2457
  { mergeValues: (renders) => `[${renders.join(", ")}]` }
2099
2458
  );
2100
2459
  },
2101
2460
  visitBooleanType(booleanType, { self }) {
2102
- const encoderImports = new ImportMap().add("solanaCodecsDataStructures", "getBooleanEncoder");
2103
- const decoderImports = new ImportMap().add("solanaCodecsDataStructures", "getBooleanDecoder");
2104
- let sizeEncoder = "";
2105
- let sizeDecoder = "";
2106
- const resolvedSize = resolveNestedTypeNode3(booleanType.size);
2461
+ let sizeEncoder = fragment``;
2462
+ let sizeDecoder = fragment``;
2463
+ const resolvedSize = resolveNestedTypeNode4(booleanType.size);
2107
2464
  if (resolvedSize.format !== "u8" || resolvedSize.endian !== "le") {
2108
- const size = visit5(booleanType.size, self);
2109
- encoderImports.mergeWith(size.encoder);
2110
- decoderImports.mergeWith(size.decoder);
2111
- sizeEncoder = `{ size: ${size.encoder.content} }`;
2112
- sizeDecoder = `{ size: ${size.decoder.content} }`;
2465
+ const size = visit8(booleanType.size, self);
2466
+ sizeEncoder = fragment`{ size: ${size.encoder} }`;
2467
+ sizeDecoder = fragment`{ size: ${size.decoder} }`;
2113
2468
  }
2114
2469
  return typeManifest({
2115
- decoder: pipe24(
2116
- fragment(`getBooleanDecoder(${sizeDecoder})`),
2117
- (f) => mergeFragmentImports(f, [decoderImports])
2118
- ),
2119
- encoder: pipe24(
2120
- fragment(`getBooleanEncoder(${sizeEncoder})`),
2121
- (f) => mergeFragmentImports(f, [encoderImports])
2122
- ),
2123
- looseType: fragment("boolean"),
2124
- strictType: fragment("boolean")
2470
+ decoder: fragment`${use("getBooleanDecoder", "solanaCodecsDataStructures")}(${sizeDecoder})`,
2471
+ encoder: fragment`${use("getBooleanEncoder", "solanaCodecsDataStructures")}(${sizeEncoder})`,
2472
+ looseType: fragment`boolean`,
2473
+ strictType: fragment`boolean`
2125
2474
  });
2126
2475
  },
2127
2476
  visitBooleanValue(node) {
2128
- return typeManifest({
2129
- value: fragment(JSON.stringify(node.boolean))
2130
- });
2477
+ return typeManifest({ value: fragment`${JSON.stringify(node.boolean)}` });
2131
2478
  },
2132
2479
  visitBytesType() {
2133
- const readonlyUint8Array = pipe24(
2134
- fragment("ReadonlyUint8Array"),
2135
- (f) => addFragmentImports(f, "solanaCodecsCore", ["type ReadonlyUint8Array"])
2136
- );
2480
+ const readonlyUint8Array = use("type ReadonlyUint8Array", "solanaCodecsCore");
2137
2481
  return typeManifest({
2138
- decoder: pipe24(
2139
- fragment(`getBytesDecoder()`),
2140
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getBytesDecoder"])
2141
- ),
2142
- encoder: pipe24(
2143
- fragment(`getBytesEncoder()`),
2144
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getBytesEncoder"])
2145
- ),
2482
+ decoder: fragment`${use("getBytesDecoder", "solanaCodecsDataStructures")}()`,
2483
+ encoder: fragment`${use("getBytesEncoder", "solanaCodecsDataStructures")}()`,
2146
2484
  looseType: readonlyUint8Array,
2147
2485
  strictType: readonlyUint8Array
2148
2486
  });
2149
2487
  },
2150
2488
  visitBytesValue(node) {
2151
2489
  const bytes = getBytesFromBytesValueNode(node);
2152
- return typeManifest({
2153
- value: fragment(`new Uint8Array([${Array.from(bytes).join(", ")}])`)
2154
- });
2490
+ return typeManifest({ value: fragment`new Uint8Array([${Array.from(bytes).join(", ")}])` });
2155
2491
  },
2156
2492
  visitConstantValue(node, { self }) {
2157
2493
  if (isNode15(node.type, "bytesTypeNode") && isNode15(node.value, "bytesValueNode")) {
2158
- return visit5(node.value, self);
2494
+ return visit8(node.value, self);
2159
2495
  }
2160
2496
  return typeManifest({
2161
- value: mergeFragments(
2162
- [visit5(node.type, self).encoder, visit5(node.value, self).value],
2163
- ([encoderFunction, value]) => `${encoderFunction}.encode(${value})`
2164
- )
2497
+ value: fragment`${visit8(node.type, self).encoder}.encode(${visit8(node.value, self).value})`
2165
2498
  });
2166
2499
  },
2167
2500
  visitDateTimeType(dateTimeType, { self }) {
2168
- return visit5(dateTimeType.number, self);
2501
+ return visit8(dateTimeType.number, self);
2169
2502
  },
2170
2503
  visitDefinedType(definedType, { self }) {
2171
2504
  parentName = {
2172
2505
  loose: nameApi.dataArgsType(definedType.name),
2173
2506
  strict: nameApi.dataType(definedType.name)
2174
2507
  };
2175
- const manifest = visit5(definedType.type, self);
2508
+ const manifest = visit8(definedType.type, self);
2176
2509
  parentName = null;
2177
2510
  return manifest;
2178
2511
  },
@@ -2183,60 +2516,42 @@ function getTypeManifestVisitor(input) {
2183
2516
  const decoderFunction = nameApi.decoderFunction(node.name);
2184
2517
  const importFrom = getImportFrom(node);
2185
2518
  return typeManifest({
2186
- decoder: pipe24(
2187
- fragment(`${decoderFunction}()`),
2188
- (f) => addFragmentImports(f, importFrom, [decoderFunction])
2189
- ),
2190
- encoder: pipe24(
2191
- fragment(`${encoderFunction}()`),
2192
- (f) => addFragmentImports(f, importFrom, [encoderFunction])
2193
- ),
2194
- looseType: pipe24(
2195
- fragment(looseName),
2196
- (f) => addFragmentImports(f, importFrom, [`type ${looseName}`])
2197
- ),
2198
- strictType: pipe24(
2199
- fragment(strictName),
2200
- (f) => addFragmentImports(f, importFrom, [`type ${strictName}`])
2201
- )
2519
+ decoder: fragment`${use(decoderFunction, importFrom)}()`,
2520
+ encoder: fragment`${use(encoderFunction, importFrom)}()`,
2521
+ looseType: use(`type ${looseName}`, importFrom),
2522
+ strictType: use(`type ${strictName}`, importFrom)
2202
2523
  });
2203
2524
  },
2204
2525
  visitEnumEmptyVariantType(enumEmptyVariantType) {
2205
- const discriminator = nameApi.discriminatedUnionDiscriminator(camelCase10(parentName?.strict ?? ""));
2526
+ const discriminator = nameApi.discriminatedUnionDiscriminator(camelCase13(parentName?.strict ?? ""));
2206
2527
  const name = nameApi.discriminatedUnionVariant(enumEmptyVariantType.name);
2207
2528
  const kindAttribute = `${discriminator}: "${name}"`;
2208
2529
  return typeManifest({
2209
- decoder: pipe24(
2210
- fragment(`['${name}', getUnitDecoder()]`),
2211
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getUnitDecoder"])
2212
- ),
2213
- encoder: pipe24(
2214
- fragment(`['${name}', getUnitEncoder()]`),
2215
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getUnitEncoder"])
2216
- ),
2217
- looseType: fragment(`{ ${kindAttribute} }`),
2218
- strictType: fragment(`{ ${kindAttribute} }`)
2530
+ decoder: fragment`['${name}', ${use("getUnitDecoder", "solanaCodecsDataStructures")}()]`,
2531
+ encoder: fragment`['${name}', ${use("getUnitEncoder", "solanaCodecsDataStructures")}()]`,
2532
+ looseType: fragment`{ ${kindAttribute} }`,
2533
+ strictType: fragment`{ ${kindAttribute} }`
2219
2534
  });
2220
2535
  },
2221
2536
  visitEnumStructVariantType(enumStructVariantType, { self }) {
2222
2537
  const currentParentName = parentName;
2223
2538
  const discriminator = nameApi.discriminatedUnionDiscriminator(
2224
- camelCase10(currentParentName?.strict ?? "")
2539
+ camelCase13(currentParentName?.strict ?? "")
2225
2540
  );
2226
2541
  const name = nameApi.discriminatedUnionVariant(enumStructVariantType.name);
2227
2542
  const kindAttribute = `${discriminator}: "${name}"`;
2228
2543
  parentName = null;
2229
- const structManifest = visit5(enumStructVariantType.struct, self);
2544
+ const structManifest = visit8(enumStructVariantType.struct, self);
2230
2545
  parentName = currentParentName;
2231
2546
  return typeManifest({
2232
2547
  ...structManifest,
2233
- decoder: pipe24(structManifest.decoder, (f) => mapFragmentContent11(f, (c) => `['${name}', ${c}]`)),
2234
- encoder: pipe24(structManifest.encoder, (f) => mapFragmentContent11(f, (c) => `['${name}', ${c}]`)),
2235
- looseType: pipe24(
2548
+ decoder: fragment`['${name}', ${structManifest.decoder}]`,
2549
+ encoder: fragment`['${name}', ${structManifest.encoder}]`,
2550
+ looseType: pipe15(
2236
2551
  structManifest.looseType,
2237
2552
  (f) => mapFragmentContent11(f, (c) => `{ ${kindAttribute},${c.slice(1, -1)}}`)
2238
2553
  ),
2239
- strictType: pipe24(
2554
+ strictType: pipe15(
2240
2555
  structManifest.strictType,
2241
2556
  (f) => mapFragmentContent11(f, (c) => `{ ${kindAttribute},${c.slice(1, -1)}}`)
2242
2557
  )
@@ -2245,7 +2560,7 @@ function getTypeManifestVisitor(input) {
2245
2560
  visitEnumTupleVariantType(enumTupleVariantType, { self }) {
2246
2561
  const currentParentName = parentName;
2247
2562
  const discriminator = nameApi.discriminatedUnionDiscriminator(
2248
- camelCase10(currentParentName?.strict ?? "")
2563
+ camelCase13(currentParentName?.strict ?? "")
2249
2564
  );
2250
2565
  const name = nameApi.discriminatedUnionVariant(enumTupleVariantType.name);
2251
2566
  const kindAttribute = `${discriminator}: "${name}"`;
@@ -2256,17 +2571,17 @@ function getTypeManifestVisitor(input) {
2256
2571
  })
2257
2572
  ]);
2258
2573
  parentName = null;
2259
- const structManifest = visit5(struct, self);
2574
+ const structManifest = visit8(struct, self);
2260
2575
  parentName = currentParentName;
2261
2576
  return typeManifest({
2262
2577
  ...structManifest,
2263
- decoder: pipe24(structManifest.decoder, (f) => mapFragmentContent11(f, (c) => `['${name}', ${c}]`)),
2264
- encoder: pipe24(structManifest.encoder, (f) => mapFragmentContent11(f, (c) => `['${name}', ${c}]`)),
2265
- looseType: pipe24(
2578
+ decoder: fragment`['${name}', ${structManifest.decoder}]`,
2579
+ encoder: fragment`['${name}', ${structManifest.encoder}]`,
2580
+ looseType: pipe15(
2266
2581
  structManifest.looseType,
2267
2582
  (f) => mapFragmentContent11(f, (c) => `{ ${kindAttribute},${c.slice(1, -1)}}`)
2268
2583
  ),
2269
- strictType: pipe24(
2584
+ strictType: pipe15(
2270
2585
  structManifest.strictType,
2271
2586
  (f) => mapFragmentContent11(f, (c) => `{ ${kindAttribute},${c.slice(1, -1)}}`)
2272
2587
  )
@@ -2274,27 +2589,29 @@ function getTypeManifestVisitor(input) {
2274
2589
  },
2275
2590
  visitEnumType(enumType, { self }) {
2276
2591
  const currentParentName = parentName;
2277
- const encoderImports = new ImportMap();
2278
- const decoderImports = new ImportMap();
2279
2592
  const encoderOptions = [];
2280
2593
  const decoderOptions = [];
2281
- const enumSize = resolveNestedTypeNode3(enumType.size);
2594
+ const enumSize = resolveNestedTypeNode4(enumType.size);
2282
2595
  if (enumSize.format !== "u8" || enumSize.endian !== "le") {
2283
- const sizeManifest = visit5(enumType.size, self);
2284
- encoderImports.mergeWith(sizeManifest.encoder);
2285
- decoderImports.mergeWith(sizeManifest.decoder);
2286
- encoderOptions.push(`size: ${sizeManifest.encoder.content}`);
2287
- decoderOptions.push(`size: ${sizeManifest.decoder.content}`);
2596
+ const sizeManifest = visit8(enumType.size, self);
2597
+ encoderOptions.push(fragment`size: ${sizeManifest.encoder}`);
2598
+ decoderOptions.push(fragment`size: ${sizeManifest.decoder}`);
2288
2599
  }
2289
2600
  const discriminator = nameApi.discriminatedUnionDiscriminator(
2290
- camelCase10(currentParentName?.strict ?? "")
2601
+ camelCase13(currentParentName?.strict ?? "")
2291
2602
  );
2292
2603
  if (!isScalarEnum(enumType) && discriminator !== "__kind") {
2293
- encoderOptions.push(`discriminator: '${discriminator}'`);
2294
- decoderOptions.push(`discriminator: '${discriminator}'`);
2604
+ encoderOptions.push(fragment`discriminator: '${discriminator}'`);
2605
+ decoderOptions.push(fragment`discriminator: '${discriminator}'`);
2295
2606
  }
2296
- const encoderOptionsAsString = encoderOptions.length > 0 ? `, { ${encoderOptions.join(", ")} }` : "";
2297
- const decoderOptionsAsString = decoderOptions.length > 0 ? `, { ${decoderOptions.join(", ")} }` : "";
2607
+ const encoderOptionsFragment = mergeFragments(
2608
+ encoderOptions,
2609
+ (cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
2610
+ );
2611
+ const decoderOptionsFragment = mergeFragments(
2612
+ decoderOptions,
2613
+ (cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
2614
+ );
2298
2615
  if (isScalarEnum(enumType)) {
2299
2616
  if (currentParentName === null) {
2300
2617
  throw new Error(
@@ -2303,23 +2620,15 @@ function getTypeManifestVisitor(input) {
2303
2620
  }
2304
2621
  const variantNames = enumType.variants.map(({ name }) => nameApi.enumVariant(name));
2305
2622
  return typeManifest({
2306
- decoder: pipe24(
2307
- fragment(`getEnumDecoder(${currentParentName.strict + decoderOptionsAsString})`),
2308
- (f) => mergeFragmentImports(f, [decoderImports]),
2309
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getEnumDecoder"])
2310
- ),
2311
- encoder: pipe24(
2312
- fragment(`getEnumEncoder(${currentParentName.strict + encoderOptionsAsString})`),
2313
- (f) => mergeFragmentImports(f, [encoderImports]),
2314
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getEnumEncoder"])
2315
- ),
2623
+ decoder: fragment`${use("getEnumDecoder", "solanaCodecsDataStructures")}(${currentParentName.strict}${decoderOptionsFragment})`,
2624
+ encoder: fragment`${use("getEnumEncoder", "solanaCodecsDataStructures")}(${currentParentName.strict}${encoderOptionsFragment})`,
2316
2625
  isEnum: true,
2317
- looseType: fragment(`{ ${variantNames.join(", ")} }`),
2318
- strictType: fragment(`{ ${variantNames.join(", ")} }`)
2626
+ looseType: fragment`{ ${variantNames.join(", ")} }`,
2627
+ strictType: fragment`{ ${variantNames.join(", ")} }`
2319
2628
  });
2320
2629
  }
2321
2630
  const mergedManifest = mergeTypeManifests(
2322
- enumType.variants.map((variant) => visit5(variant, self)),
2631
+ enumType.variants.map((variant) => visit8(variant, self)),
2323
2632
  {
2324
2633
  mergeCodecs: (renders) => renders.join(", "),
2325
2634
  mergeTypes: (renders) => renders.join(" | ")
@@ -2327,24 +2636,8 @@ function getTypeManifestVisitor(input) {
2327
2636
  );
2328
2637
  return typeManifest({
2329
2638
  ...mergedManifest,
2330
- decoder: pipe24(
2331
- mergedManifest.decoder,
2332
- (f) => mapFragmentContent11(
2333
- f,
2334
- (c) => `getDiscriminatedUnionDecoder([${c}]${decoderOptionsAsString})`
2335
- ),
2336
- (f) => mergeFragmentImports(f, [decoderImports]),
2337
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getDiscriminatedUnionDecoder"])
2338
- ),
2339
- encoder: pipe24(
2340
- mergedManifest.encoder,
2341
- (f) => mapFragmentContent11(
2342
- f,
2343
- (c) => `getDiscriminatedUnionEncoder([${c}]${encoderOptionsAsString})`
2344
- ),
2345
- (f) => mergeFragmentImports(f, [encoderImports]),
2346
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getDiscriminatedUnionEncoder"])
2347
- )
2639
+ decoder: fragment`${use("getDiscriminatedUnionDecoder", "solanaCodecsDataStructures")}([${mergedManifest.decoder}]${decoderOptionsFragment})`,
2640
+ encoder: fragment`${use("getDiscriminatedUnionEncoder", "solanaCodecsDataStructures")}([${mergedManifest.encoder}]${encoderOptionsFragment})`
2348
2641
  });
2349
2642
  },
2350
2643
  visitEnumValue(node, { self }) {
@@ -2358,7 +2651,7 @@ function getTypeManifestVisitor(input) {
2358
2651
  const variantName2 = nameApi.enumVariant(node.variant);
2359
2652
  return typeManifest({
2360
2653
  ...manifest,
2361
- value: pipe24(
2654
+ value: pipe15(
2362
2655
  manifest.value,
2363
2656
  (f) => setFragmentContent2(f, `${enumName}.${variantName2}`),
2364
2657
  (f) => addFragmentImports(f, importFrom, [enumName])
@@ -2369,7 +2662,7 @@ function getTypeManifestVisitor(input) {
2369
2662
  if (!node.value) {
2370
2663
  return typeManifest({
2371
2664
  ...manifest,
2372
- value: pipe24(
2665
+ value: pipe15(
2373
2666
  manifest.value,
2374
2667
  (f) => setFragmentContent2(f, `${enumFunction}('${variantName}')`),
2375
2668
  (f) => addFragmentImports(f, importFrom, [enumFunction])
@@ -2378,85 +2671,53 @@ function getTypeManifestVisitor(input) {
2378
2671
  }
2379
2672
  return typeManifest({
2380
2673
  ...manifest,
2381
- value: pipe24(
2382
- visit5(node.value, self).value,
2674
+ value: pipe15(
2675
+ visit8(node.value, self).value,
2383
2676
  (f) => mapFragmentContent11(f, (c) => `${enumFunction}('${variantName}', ${c})`),
2384
2677
  (f) => addFragmentImports(f, importFrom, [enumFunction])
2385
2678
  )
2386
2679
  });
2387
2680
  },
2388
2681
  visitFixedSizeType(node, { self }) {
2389
- const manifest = visit5(node.type, self);
2682
+ const manifest = visit8(node.type, self);
2390
2683
  return typeManifest({
2391
2684
  ...manifest,
2392
- decoder: pipe24(
2393
- manifest.decoder,
2394
- (f) => mapFragmentContent11(f, (c) => `fixDecoderSize(${c}, ${node.size})`),
2395
- (f) => addFragmentImports(f, "solanaCodecsCore", ["fixDecoderSize"])
2396
- ),
2397
- encoder: pipe24(
2398
- manifest.encoder,
2399
- (f) => mapFragmentContent11(f, (c) => `fixEncoderSize(${c}, ${node.size})`),
2400
- (f) => addFragmentImports(f, "solanaCodecsCore", ["fixEncoderSize"])
2401
- )
2685
+ decoder: fragment`${use("fixDecoderSize", "solanaCodecsCore")}(${manifest.decoder}, ${node.size})`,
2686
+ encoder: fragment`${use("fixEncoderSize", "solanaCodecsCore")}(${manifest.encoder}, ${node.size})`
2402
2687
  });
2403
2688
  },
2404
2689
  visitHiddenPrefixType(node, { self }) {
2405
- const manifest = visit5(node.type, self);
2406
- const prefixes = node.prefix.map((c) => visit5(c, self).value);
2407
- const prefixEncoders = pipe24(
2408
- mergeFragments(prefixes, (contents) => contents.map((c) => `getConstantEncoder(${c})`).join(", ")),
2690
+ const manifest = visit8(node.type, self);
2691
+ const prefixes = node.prefix.map((c) => visit8(c, self).value);
2692
+ const prefixEncoders = pipe15(
2693
+ mergeFragments(prefixes, (cs) => cs.map((c) => `getConstantEncoder(${c})`).join(", ")),
2409
2694
  (f) => addFragmentImports(f, "solanaCodecsCore", ["getConstantEncoder"])
2410
2695
  );
2411
- const prefixDecoders = pipe24(
2412
- mergeFragments(prefixes, (contents) => contents.map((c) => `getConstantDecoder(${c})`).join(", ")),
2696
+ const prefixDecoders = pipe15(
2697
+ mergeFragments(prefixes, (cs) => cs.map((c) => `getConstantDecoder(${c})`).join(", ")),
2413
2698
  (f) => addFragmentImports(f, "solanaCodecsCore", ["getConstantDecoder"])
2414
2699
  );
2415
2700
  return typeManifest({
2416
2701
  ...manifest,
2417
- decoder: pipe24(
2418
- mergeFragments(
2419
- [manifest.decoder, prefixDecoders],
2420
- ([child, prefixes2]) => `getHiddenPrefixDecoder(${child}, [${prefixes2}])`
2421
- ),
2422
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getHiddenPrefixDecoder"])
2423
- ),
2424
- encoder: pipe24(
2425
- mergeFragments(
2426
- [manifest.encoder, prefixEncoders],
2427
- ([child, prefixes2]) => `getHiddenPrefixEncoder(${child}, [${prefixes2}])`
2428
- ),
2429
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getHiddenPrefixEncoder"])
2430
- )
2702
+ decoder: fragment`${use("getHiddenPrefixDecoder", "solanaCodecsDataStructures")}(${manifest.decoder}, [${prefixDecoders}])`,
2703
+ encoder: fragment`${use("getHiddenPrefixEncoder", "solanaCodecsDataStructures")}(${manifest.encoder}, [${prefixEncoders}])`
2431
2704
  });
2432
2705
  },
2433
2706
  visitHiddenSuffixType(node, { self }) {
2434
- const manifest = visit5(node.type, self);
2435
- const suffixes = node.suffix.map((c) => visit5(c, self).value);
2436
- const suffixEncoders = pipe24(
2437
- mergeFragments(suffixes, (contents) => contents.map((c) => `getConstantEncoder(${c})`).join(", ")),
2707
+ const manifest = visit8(node.type, self);
2708
+ const suffixes = node.suffix.map((c) => visit8(c, self).value);
2709
+ const suffixEncoders = pipe15(
2710
+ mergeFragments(suffixes, (cs) => cs.map((c) => `getConstantEncoder(${c})`).join(", ")),
2438
2711
  (f) => addFragmentImports(f, "solanaCodecsCore", ["getConstantEncoder"])
2439
2712
  );
2440
- const suffixDecoders = pipe24(
2441
- mergeFragments(suffixes, (contents) => contents.map((c) => `getConstantDecoder(${c})`).join(", ")),
2713
+ const suffixDecoders = pipe15(
2714
+ mergeFragments(suffixes, (cs) => cs.map((c) => `getConstantDecoder(${c})`).join(", ")),
2442
2715
  (f) => addFragmentImports(f, "solanaCodecsCore", ["getConstantDecoder"])
2443
2716
  );
2444
2717
  return typeManifest({
2445
2718
  ...manifest,
2446
- decoder: pipe24(
2447
- mergeFragments(
2448
- [manifest.decoder, suffixDecoders],
2449
- ([child, suffixes2]) => `getHiddenSuffixDecoder(${child}, [${suffixes2}])`
2450
- ),
2451
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getHiddenSuffixDecoder"])
2452
- ),
2453
- encoder: pipe24(
2454
- mergeFragments(
2455
- [manifest.encoder, suffixEncoders],
2456
- ([child, suffixes2]) => `getHiddenSuffixEncoder(${child}, [${suffixes2}])`
2457
- ),
2458
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getHiddenSuffixEncoder"])
2459
- )
2719
+ decoder: fragment`${use("getHiddenSuffixDecoder", "solanaCodecsDataStructures")}(${manifest.decoder}, [${suffixDecoders}])`,
2720
+ encoder: fragment`${use("getHiddenSuffixEncoder", "solanaCodecsDataStructures")}(${manifest.encoder}, [${suffixEncoders}])`
2460
2721
  });
2461
2722
  },
2462
2723
  visitInstruction(instruction, { self }) {
@@ -2466,142 +2727,95 @@ function getTypeManifestVisitor(input) {
2466
2727
  strict: nameApi.dataType(instructionDataName)
2467
2728
  };
2468
2729
  const link = customInstructionData.get(instruction.name)?.linkNode;
2469
- const struct = structTypeNodeFromInstructionArgumentNodes4(instruction.arguments);
2470
- const manifest = link ? visit5(link, self) : visit5(struct, self);
2730
+ const struct = structTypeNodeFromInstructionArgumentNodes5(instruction.arguments);
2731
+ const manifest = link ? visit8(link, self) : visit8(struct, self);
2471
2732
  parentName = null;
2472
2733
  return manifest;
2473
2734
  },
2474
2735
  visitMapEntryValue(node, { self }) {
2475
- return mergeTypeManifests([visit5(node.key, self), visit5(node.value, self)], {
2736
+ return mergeTypeManifests([visit8(node.key, self), visit8(node.value, self)], {
2476
2737
  mergeValues: (renders) => `[${renders.join(", ")}]`
2477
2738
  });
2478
2739
  },
2479
2740
  visitMapType(mapType, { self }) {
2480
- const key = visit5(mapType.key, self);
2481
- const value = visit5(mapType.value, self);
2741
+ const key = visit8(mapType.key, self);
2742
+ const value = visit8(mapType.value, self);
2482
2743
  const mergedManifest = mergeTypeManifests([key, value], {
2483
2744
  mergeCodecs: ([k, v]) => `${k}, ${v}`,
2484
2745
  mergeTypes: ([k, v]) => `Map<${k}, ${v}>`
2485
2746
  });
2486
2747
  const sizeManifest = getArrayLikeSizeOption(mapType.count, self);
2487
- const encoderOptions = sizeManifest.encoder.content ? `, { ${sizeManifest.encoder.content} }` : "";
2488
- const decoderOptions = sizeManifest.decoder.content ? `, { ${sizeManifest.decoder.content} }` : "";
2748
+ const encoderOptions = sizeManifest.encoder ? fragment`, { ${sizeManifest.encoder} }` : "";
2749
+ const decoderOptions = sizeManifest.decoder ? fragment`, { ${sizeManifest.decoder} }` : "";
2489
2750
  return typeManifest({
2490
2751
  ...mergedManifest,
2491
- decoder: pipe24(
2492
- mergedManifest.decoder,
2493
- (f) => mapFragmentContent11(f, (c) => `getMapDecoder(${c}${decoderOptions})`),
2494
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getMapDecoder"])
2495
- ),
2496
- encoder: pipe24(
2497
- mergedManifest.encoder,
2498
- (f) => mapFragmentContent11(f, (c) => `getMapEncoder(${c}${encoderOptions})`),
2499
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getMapEncoder"])
2500
- )
2752
+ decoder: fragment`${use("getMapDecoder", "solanaCodecsDataStructures")}(${mergedManifest.decoder}${decoderOptions})`,
2753
+ encoder: fragment`${use("getMapEncoder", "solanaCodecsDataStructures")}(${mergedManifest.encoder}${encoderOptions})`
2501
2754
  });
2502
2755
  },
2503
2756
  visitMapValue(node, { self }) {
2504
- const entryFragments = node.entries.map((entry) => visit5(entry, self));
2757
+ const entryFragments = node.entries.map((entry) => visit8(entry, self));
2505
2758
  return mergeTypeManifests(entryFragments, {
2506
2759
  mergeValues: (renders) => `new Map([${renders.join(", ")}])`
2507
2760
  });
2508
2761
  },
2509
2762
  visitNoneValue() {
2510
2763
  return typeManifest({
2511
- value: pipe24(fragment("none()"), (f) => addFragmentImports(f, "solanaOptions", ["none"]))
2764
+ value: fragment`${use("none", "solanaOptions")}()`
2512
2765
  });
2513
2766
  },
2514
2767
  visitNumberType(numberType) {
2515
- const encoderFunction = nameApi.encoderFunction(numberType.format);
2516
- const decoderFunction = nameApi.decoderFunction(numberType.format);
2768
+ const encoderFunction = use(nameApi.encoderFunction(numberType.format), "solanaCodecsNumbers");
2769
+ const decoderFunction = use(nameApi.decoderFunction(numberType.format), "solanaCodecsNumbers");
2517
2770
  const isBigNumber = ["u64", "u128", "i64", "i128"].includes(numberType.format);
2518
- const encoderImports = new ImportMap().add("solanaCodecsNumbers", encoderFunction);
2519
- const decoderImports = new ImportMap().add("solanaCodecsNumbers", decoderFunction);
2520
- let endianness = "";
2521
- if (numberType.endian === "be") {
2522
- encoderImports.add("solanaCodecsNumbers", "Endian");
2523
- decoderImports.add("solanaCodecsNumbers", "Endian");
2524
- endianness = "{ endian: Endian.Big }";
2525
- }
2771
+ const endianness = numberType.endian === "be" ? fragment`{ endian: ${use("Endian", "solanaCodecsNumbers")}.Big }` : "";
2526
2772
  return typeManifest({
2527
- decoder: pipe24(
2528
- fragment(`${decoderFunction}(${endianness})`),
2529
- (f) => mergeFragmentImports(f, [decoderImports])
2530
- ),
2531
- encoder: pipe24(
2532
- fragment(`${encoderFunction}(${endianness})`),
2533
- (f) => mergeFragmentImports(f, [encoderImports])
2534
- ),
2535
- looseType: fragment(isBigNumber ? "number | bigint" : "number"),
2536
- strictType: fragment(isBigNumber ? "bigint" : "number")
2773
+ decoder: fragment`${decoderFunction}(${endianness})`,
2774
+ encoder: fragment`${encoderFunction}(${endianness})`,
2775
+ looseType: fragment`${isBigNumber ? "number | bigint" : "number"}`,
2776
+ strictType: fragment`${isBigNumber ? "bigint" : "number"}`
2537
2777
  });
2538
2778
  },
2539
2779
  visitNumberValue(node) {
2540
- return typeManifest({
2541
- value: fragment(JSON.stringify(node.number))
2542
- });
2780
+ return typeManifest({ value: fragment`${JSON.stringify(node.number)}` });
2543
2781
  },
2544
2782
  visitOptionType(optionType, { self }) {
2545
- const childManifest = visit5(optionType.item, self);
2783
+ const childManifest = visit8(optionType.item, self);
2546
2784
  const encoderOptions = [];
2547
2785
  const decoderOptions = [];
2548
- const encoderImports = new ImportMap();
2549
- const decoderImports = new ImportMap();
2550
- const optionPrefix = resolveNestedTypeNode3(optionType.prefix);
2786
+ const optionPrefix = resolveNestedTypeNode4(optionType.prefix);
2551
2787
  if (optionPrefix.format !== "u8" || optionPrefix.endian !== "le") {
2552
- const prefixManifest = visit5(optionType.prefix, self);
2553
- encoderImports.mergeWith(prefixManifest.encoder);
2554
- decoderImports.mergeWith(prefixManifest.decoder);
2555
- encoderOptions.push(`prefix: ${prefixManifest.encoder.content}`);
2556
- decoderOptions.push(`prefix: ${prefixManifest.decoder.content}`);
2788
+ const prefixManifest = visit8(optionType.prefix, self);
2789
+ encoderOptions.push(fragment`prefix: ${prefixManifest.encoder}`);
2790
+ decoderOptions.push(fragment`prefix: ${prefixManifest.decoder}`);
2557
2791
  }
2558
2792
  if (optionType.fixed) {
2559
- encoderOptions.push(`noneValue: "zeroes"`);
2560
- decoderOptions.push(`noneValue: "zeroes"`);
2793
+ encoderOptions.push(fragment`noneValue: "zeroes"`);
2794
+ decoderOptions.push(fragment`noneValue: "zeroes"`);
2561
2795
  }
2562
- const encoderOptionsAsString = encoderOptions.length > 0 ? `, { ${encoderOptions.join(", ")} }` : "";
2563
- const decoderOptionsAsString = decoderOptions.length > 0 ? `, { ${decoderOptions.join(", ")} }` : "";
2796
+ const encoderOptionsFragment = mergeFragments(
2797
+ encoderOptions,
2798
+ (cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
2799
+ );
2800
+ const decoderOptionsFragment = mergeFragments(
2801
+ decoderOptions,
2802
+ (cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
2803
+ );
2564
2804
  return typeManifest({
2565
2805
  ...childManifest,
2566
- decoder: pipe24(
2567
- childManifest.decoder,
2568
- (f) => mapFragmentContent11(f, (c) => `getOptionDecoder(${c + decoderOptionsAsString})`),
2569
- (f) => addFragmentImports(f, "solanaOptions", ["getOptionDecoder"]),
2570
- (f) => mergeFragmentImports(f, [decoderImports])
2571
- ),
2572
- encoder: pipe24(
2573
- childManifest.encoder,
2574
- (f) => mapFragmentContent11(f, (c) => `getOptionEncoder(${c + encoderOptionsAsString})`),
2575
- (f) => addFragmentImports(f, "solanaOptions", ["getOptionEncoder"]),
2576
- (f) => mergeFragmentImports(f, [encoderImports])
2577
- ),
2578
- looseType: pipe24(
2579
- childManifest.looseType,
2580
- (f) => mapFragmentContent11(f, (c) => `OptionOrNullable<${c}>`),
2581
- (f) => addFragmentImports(f, "solanaOptions", ["type OptionOrNullable"])
2582
- ),
2583
- strictType: pipe24(
2584
- childManifest.strictType,
2585
- (f) => mapFragmentContent11(f, (c) => `Option<${c}>`),
2586
- (f) => addFragmentImports(f, "solanaOptions", ["type Option"])
2587
- )
2806
+ decoder: fragment`${use("getOptionDecoder", "solanaOptions")}(${childManifest.decoder}${decoderOptionsFragment})`,
2807
+ encoder: fragment`${use("getOptionEncoder", "solanaOptions")}(${childManifest.encoder}${encoderOptionsFragment})`,
2808
+ looseType: fragment`${use("type OptionOrNullable", "solanaOptions")}<${childManifest.looseType}>`,
2809
+ strictType: fragment`${use("type Option", "solanaOptions")}<${childManifest.strictType}>`
2588
2810
  });
2589
2811
  },
2590
2812
  visitPostOffsetType(node, { self }) {
2591
- const manifest = visit5(node.type, self);
2813
+ const manifest = visit8(node.type, self);
2592
2814
  if (node.strategy === "padded") {
2593
2815
  return typeManifest({
2594
2816
  ...manifest,
2595
- decoder: pipe24(
2596
- manifest.decoder,
2597
- (f) => mapFragmentContent11(f, (c) => `padRightDecoder(${c}, ${node.offset})`),
2598
- (f) => addFragmentImports(f, "solanaCodecsCore", ["padRightDecoder"])
2599
- ),
2600
- encoder: pipe24(
2601
- manifest.encoder,
2602
- (f) => mapFragmentContent11(f, (c) => `padRightEncoder(${c}, ${node.offset})`),
2603
- (f) => addFragmentImports(f, "solanaCodecsCore", ["padRightEncoder"])
2604
- )
2817
+ decoder: fragment`${use("padRightDecoder", "solanaCodecsCore")}(${manifest.decoder}, ${node.offset})`,
2818
+ encoder: fragment`${use("padRightEncoder", "solanaCodecsCore")}(${manifest.encoder}, ${node.offset})`
2605
2819
  });
2606
2820
  }
2607
2821
  const fn = (() => {
@@ -2617,33 +2831,17 @@ function getTypeManifestVisitor(input) {
2617
2831
  })();
2618
2832
  return typeManifest({
2619
2833
  ...manifest,
2620
- decoder: pipe24(
2621
- manifest.decoder,
2622
- (f) => mapFragmentContent11(f, (c) => `offsetDecoder(${c}, { postOffset: ${fn} })`),
2623
- (f) => addFragmentImports(f, "solanaCodecsCore", ["offsetDecoder"])
2624
- ),
2625
- encoder: pipe24(
2626
- manifest.encoder,
2627
- (f) => mapFragmentContent11(f, (c) => `offsetEncoder(${c}, { postOffset: ${fn} })`),
2628
- (f) => addFragmentImports(f, "solanaCodecsCore", ["offsetEncoder"])
2629
- )
2834
+ decoder: fragment`${use("offsetDecoder", "solanaCodecsCore")}(${manifest.decoder}, { postOffset: ${fn} })`,
2835
+ encoder: fragment`${use("offsetEncoder", "solanaCodecsCore")}(${manifest.encoder}, { postOffset: ${fn} })`
2630
2836
  });
2631
2837
  },
2632
2838
  visitPreOffsetType(node, { self }) {
2633
- const manifest = visit5(node.type, self);
2839
+ const manifest = visit8(node.type, self);
2634
2840
  if (node.strategy === "padded") {
2635
2841
  return typeManifest({
2636
2842
  ...manifest,
2637
- decoder: pipe24(
2638
- manifest.decoder,
2639
- (f) => mapFragmentContent11(f, (c) => `padLeftDecoder(${c}, ${node.offset})`),
2640
- (f) => addFragmentImports(f, "solanaCodecsCore", ["padLeftDecoder"])
2641
- ),
2642
- encoder: pipe24(
2643
- manifest.encoder,
2644
- (f) => mapFragmentContent11(f, (c) => `padLeftEncoder(${c}, ${node.offset})`),
2645
- (f) => addFragmentImports(f, "solanaCodecsCore", ["padLeftEncoder"])
2646
- )
2843
+ decoder: fragment`${use("padLeftDecoder", "solanaCodecsCore")}(${manifest.decoder}, ${node.offset})`,
2844
+ encoder: fragment`${use("padLeftEncoder", "solanaCodecsCore")}(${manifest.encoder}, ${node.offset})`
2647
2845
  });
2648
2846
  }
2649
2847
  const fn = (() => {
@@ -2657,174 +2855,88 @@ function getTypeManifestVisitor(input) {
2657
2855
  })();
2658
2856
  return typeManifest({
2659
2857
  ...manifest,
2660
- decoder: pipe24(
2661
- manifest.decoder,
2662
- (f) => mapFragmentContent11(f, (c) => `offsetDecoder(${c}, { preOffset: ${fn} })`),
2663
- (f) => addFragmentImports(f, "solanaCodecsCore", ["offsetDecoder"])
2664
- ),
2665
- encoder: pipe24(
2666
- manifest.encoder,
2667
- (f) => mapFragmentContent11(f, (c) => `offsetEncoder(${c}, { preOffset: ${fn} })`),
2668
- (f) => addFragmentImports(f, "solanaCodecsCore", ["offsetEncoder"])
2669
- )
2858
+ decoder: fragment`${use("offsetDecoder", "solanaCodecsCore")}(${manifest.decoder}, { preOffset: ${fn} })`,
2859
+ encoder: fragment`${use("offsetEncoder", "solanaCodecsCore")}(${manifest.encoder}, { preOffset: ${fn} })`
2670
2860
  });
2671
2861
  },
2672
2862
  visitPublicKeyType() {
2673
- const addressFragment = pipe24(
2674
- fragment("Address"),
2675
- (f) => addFragmentImports(f, "solanaAddresses", ["type Address"])
2676
- );
2677
2863
  return typeManifest({
2678
- decoder: pipe24(
2679
- fragment("getAddressDecoder()"),
2680
- (f) => addFragmentImports(f, "solanaAddresses", ["getAddressDecoder"])
2681
- ),
2682
- encoder: pipe24(
2683
- fragment("getAddressEncoder()"),
2684
- (f) => addFragmentImports(f, "solanaAddresses", ["getAddressEncoder"])
2685
- ),
2686
- looseType: addressFragment,
2687
- strictType: addressFragment
2864
+ decoder: fragment`${use("getAddressDecoder", "solanaAddresses")}()`,
2865
+ encoder: fragment`${use("getAddressEncoder", "solanaAddresses")}()`,
2866
+ looseType: use("type Address", "solanaAddresses"),
2867
+ strictType: use("type Address", "solanaAddresses")
2688
2868
  });
2689
2869
  },
2690
2870
  visitPublicKeyValue(node) {
2691
2871
  return typeManifest({
2692
- value: pipe24(
2693
- fragment(`address("${node.publicKey}")`),
2694
- (f) => addFragmentImports(f, "solanaAddresses", ["address"])
2695
- )
2872
+ value: fragment`${use("address", "solanaAddresses")}("${node.publicKey}")`
2696
2873
  });
2697
2874
  },
2698
2875
  visitRemainderOptionType(node, { self }) {
2699
- const childManifest = visit5(node.item, self);
2876
+ const childManifest = visit8(node.item, self);
2700
2877
  const encoderOptions = ["prefix: null"];
2701
2878
  const decoderOptions = ["prefix: null"];
2702
2879
  const encoderOptionsAsString = encoderOptions.length > 0 ? `, { ${encoderOptions.join(", ")} }` : "";
2703
2880
  const decoderOptionsAsString = decoderOptions.length > 0 ? `, { ${decoderOptions.join(", ")} }` : "";
2704
2881
  return typeManifest({
2705
2882
  ...childManifest,
2706
- decoder: pipe24(
2707
- childManifest.decoder,
2708
- (f) => mapFragmentContent11(f, (c) => `getOptionDecoder(${c + decoderOptionsAsString})`),
2709
- (f) => addFragmentImports(f, "solanaOptions", ["getOptionDecoder"])
2710
- ),
2711
- encoder: pipe24(
2712
- childManifest.encoder,
2713
- (f) => mapFragmentContent11(f, (c) => `getOptionEncoder(${c + encoderOptionsAsString})`),
2714
- (f) => addFragmentImports(f, "solanaOptions", ["getOptionEncoder"])
2715
- ),
2716
- looseType: pipe24(
2717
- childManifest.looseType,
2718
- (f) => mapFragmentContent11(f, (c) => `OptionOrNullable<${c}>`),
2719
- (f) => addFragmentImports(f, "solanaOptions", ["type OptionOrNullable"])
2720
- ),
2721
- strictType: pipe24(
2722
- childManifest.strictType,
2723
- (f) => mapFragmentContent11(f, (c) => `Option<${c}>`),
2724
- (f) => addFragmentImports(f, "solanaOptions", ["type Option"])
2725
- )
2883
+ decoder: fragment`${use("getOptionDecoder", "solanaOptions")}(${childManifest.decoder}${decoderOptionsAsString})`,
2884
+ encoder: fragment`${use("getOptionEncoder", "solanaOptions")}(${childManifest.encoder}${encoderOptionsAsString})`,
2885
+ looseType: fragment`${use("type OptionOrNullable", "solanaOptions")}<${childManifest.looseType}>`,
2886
+ strictType: fragment`${use("type Option", "solanaOptions")}<${childManifest.strictType}>`
2726
2887
  });
2727
2888
  },
2728
2889
  visitSentinelType(node, { self }) {
2729
- const manifest = visit5(node.type, self);
2730
- const sentinel = visit5(node.sentinel, self).value;
2890
+ const manifest = visit8(node.type, self);
2891
+ const sentinel = visit8(node.sentinel, self).value;
2731
2892
  return typeManifest({
2732
2893
  ...manifest,
2733
- decoder: pipe24(
2734
- mergeFragments(
2735
- [manifest.decoder, sentinel],
2736
- ([child, sentinel2]) => `addDecoderSentinel(${child}, ${sentinel2})`
2737
- ),
2738
- (f) => addFragmentImports(f, "solanaCodecsCore", ["addDecoderSentinel"])
2739
- ),
2740
- encoder: pipe24(
2741
- mergeFragments(
2742
- [manifest.encoder, sentinel],
2743
- ([child, sentinel2]) => `addEncoderSentinel(${child}, ${sentinel2})`
2744
- ),
2745
- (f) => addFragmentImports(f, "solanaCodecsCore", ["addEncoderSentinel"])
2746
- )
2894
+ decoder: fragment`${use("addDecoderSentinel", "solanaCodecsCore")}(${manifest.decoder}, ${sentinel})`,
2895
+ encoder: fragment`${use("addEncoderSentinel", "solanaCodecsCore")}(${manifest.encoder}, ${sentinel})`
2747
2896
  });
2748
2897
  },
2749
2898
  visitSetType(setType, { self }) {
2750
- const childManifest = visit5(setType.item, self);
2899
+ const childManifest = visit8(setType.item, self);
2751
2900
  const sizeManifest = getArrayLikeSizeOption(setType.count, self);
2752
- const encoderOptions = sizeManifest.encoder.content ? `, { ${sizeManifest.encoder.content} }` : "";
2753
- const decoderOptions = sizeManifest.decoder.content ? `, { ${sizeManifest.decoder.content} }` : "";
2901
+ const encoderOptions = sizeManifest.encoder ? fragment`, { ${sizeManifest.encoder} }` : "";
2902
+ const decoderOptions = sizeManifest.decoder ? fragment`, { ${sizeManifest.decoder} }` : "";
2754
2903
  return typeManifest({
2755
2904
  ...childManifest,
2756
- decoder: pipe24(
2757
- childManifest.decoder,
2758
- (f) => mapFragmentContent11(f, (c) => `getSetDecoder(${c + decoderOptions})`),
2759
- (f) => mergeFragmentImports(f, [sizeManifest.decoder.imports]),
2760
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getSetDecoder"])
2761
- ),
2762
- encoder: pipe24(
2763
- childManifest.encoder,
2764
- (f) => mapFragmentContent11(f, (c) => `getSetEncoder(${c + encoderOptions})`),
2765
- (f) => mergeFragmentImports(f, [sizeManifest.encoder.imports]),
2766
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getSetEncoder"])
2767
- ),
2768
- looseType: pipe24(childManifest.looseType, (f) => mapFragmentContent11(f, (c) => `Set<${c}>`)),
2769
- strictType: pipe24(childManifest.strictType, (f) => mapFragmentContent11(f, (c) => `Set<${c}>`))
2905
+ decoder: fragment`${use("getSetDecoder", "solanaCodecsDataStructures")}(${childManifest.decoder}${decoderOptions})`,
2906
+ encoder: fragment`${use("getSetEncoder", "solanaCodecsDataStructures")}(${childManifest.encoder}${encoderOptions})`,
2907
+ looseType: fragment`Set<${childManifest.looseType}>`,
2908
+ strictType: fragment`Set<${childManifest.strictType}>`
2770
2909
  });
2771
2910
  },
2772
2911
  visitSetValue(node, { self }) {
2773
2912
  return mergeTypeManifests(
2774
- node.items.map((v) => visit5(v, self)),
2913
+ node.items.map((v) => visit8(v, self)),
2775
2914
  { mergeValues: (renders) => `new Set([${renders.join(", ")}])` }
2776
2915
  );
2777
2916
  },
2778
2917
  visitSizePrefixType(node, { self }) {
2779
- const manifest = visit5(node.type, self);
2780
- const prefix = visit5(node.prefix, self);
2918
+ const manifest = visit8(node.type, self);
2919
+ const prefix = visit8(node.prefix, self);
2781
2920
  return typeManifest({
2782
2921
  ...manifest,
2783
- decoder: pipe24(
2784
- mergeFragments(
2785
- [manifest.decoder, prefix.decoder],
2786
- ([decoder, prefix2]) => `addDecoderSizePrefix(${decoder}, ${prefix2})`
2787
- ),
2788
- (f) => addFragmentImports(f, "solanaCodecsCore", ["addDecoderSizePrefix"])
2789
- ),
2790
- encoder: pipe24(
2791
- mergeFragments(
2792
- [manifest.encoder, prefix.encoder],
2793
- ([encoder, prefix2]) => `addEncoderSizePrefix(${encoder}, ${prefix2})`
2794
- ),
2795
- (f) => addFragmentImports(f, "solanaCodecsCore", ["addEncoderSizePrefix"])
2796
- )
2922
+ decoder: fragment`${use("addDecoderSizePrefix", "solanaCodecsCore")}(${manifest.decoder}, ${prefix.decoder})`,
2923
+ encoder: fragment`${use("addEncoderSizePrefix", "solanaCodecsCore")}(${manifest.encoder}, ${prefix.encoder})`
2797
2924
  });
2798
2925
  },
2799
2926
  visitSolAmountType({ number }, { self }) {
2800
- const numberManifest = visit5(number, self);
2801
- const lamportFragment = pipe24(
2802
- fragment("Lamports"),
2803
- (f) => addFragmentImports(f, "solanaRpcTypes", ["type Lamports"])
2804
- );
2927
+ const numberManifest = visit8(number, self);
2805
2928
  return typeManifest({
2806
2929
  ...numberManifest,
2807
- decoder: pipe24(
2808
- numberManifest.decoder,
2809
- (f) => mapFragmentContent11(f, (c) => `getLamportsDecoder(${c})`),
2810
- (f) => addFragmentImports(f, "solanaRpcTypes", ["getLamportsDecoder"])
2811
- ),
2812
- encoder: pipe24(
2813
- numberManifest.encoder,
2814
- (f) => mapFragmentContent11(f, (c) => `getLamportsEncoder(${c})`),
2815
- (f) => addFragmentImports(f, "solanaRpcTypes", ["getLamportsEncoder"])
2816
- ),
2817
- looseType: lamportFragment,
2818
- strictType: lamportFragment
2930
+ decoder: fragment`${use("getLamportsDecoder", "solanaRpcTypes")}(${numberManifest.decoder})`,
2931
+ encoder: fragment`${use("getLamportsEncoder", "solanaRpcTypes")}(${numberManifest.encoder})`,
2932
+ looseType: use("type Lamports", "solanaRpcTypes"),
2933
+ strictType: use("type Lamports", "solanaRpcTypes")
2819
2934
  });
2820
2935
  },
2821
2936
  visitSomeValue(node, { self }) {
2937
+ const innerValue = visit8(node.value, self).value;
2822
2938
  return typeManifest({
2823
- value: pipe24(
2824
- visit5(node.value, self).value,
2825
- (f) => mapFragmentContent11(f, (c) => `some(${c})`),
2826
- (f) => addFragmentImports(f, "solanaOptions", ["some"])
2827
- )
2939
+ value: fragment`${use("some", "solanaOptions")}(${innerValue})`
2828
2940
  });
2829
2941
  },
2830
2942
  visitStringType(stringType) {
@@ -2843,48 +2955,28 @@ function getTypeManifestVisitor(input) {
2843
2955
  }
2844
2956
  })();
2845
2957
  return typeManifest({
2846
- decoder: pipe24(
2847
- fragment(`${decoder}()`),
2848
- (f) => addFragmentImports(f, "solanaCodecsStrings", [decoder])
2849
- ),
2850
- encoder: pipe24(
2851
- fragment(`${encoder}()`),
2852
- (f) => addFragmentImports(f, "solanaCodecsStrings", [encoder])
2853
- ),
2854
- looseType: fragment("string"),
2855
- strictType: fragment("string")
2958
+ decoder: fragment`${use(decoder, "solanaCodecsStrings")}()`,
2959
+ encoder: fragment`${use(encoder, "solanaCodecsStrings")}()`,
2960
+ looseType: fragment`string`,
2961
+ strictType: fragment`string`
2856
2962
  });
2857
2963
  },
2858
2964
  visitStringValue(node) {
2859
2965
  return typeManifest({
2860
- value: fragment(JSON.stringify(node.string))
2966
+ value: fragment`${JSON.stringify(node.string)}`
2861
2967
  });
2862
2968
  },
2863
2969
  visitStructFieldType(structFieldType, { self }) {
2864
- const name = camelCase10(structFieldType.name);
2865
- const originalChildManifest = visit5(structFieldType.type, self);
2866
- const structFieldDocs = parseDocs2(structFieldType.docs);
2867
- const docblock = structFieldDocs.length > 0 ? `
2868
- ${jsDocblock(structFieldDocs)}` : "";
2869
- const originalLooseType = originalChildManifest.looseType.content;
2970
+ const name = camelCase13(structFieldType.name);
2971
+ const originalChildManifest = visit8(structFieldType.type, self);
2972
+ let docs = getDocblockFragment(structFieldType.docs ?? [], true);
2973
+ docs = docs ? fragment`\n${docs}` : docs;
2870
2974
  const childManifest = typeManifest({
2871
2975
  ...originalChildManifest,
2872
- decoder: pipe24(
2873
- originalChildManifest.decoder,
2874
- (f) => mapFragmentContent11(f, (c) => `['${name}', ${c}]`)
2875
- ),
2876
- encoder: pipe24(
2877
- originalChildManifest.encoder,
2878
- (f) => mapFragmentContent11(f, (c) => `['${name}', ${c}]`)
2879
- ),
2880
- looseType: pipe24(
2881
- originalChildManifest.looseType,
2882
- (f) => mapFragmentContent11(f, (c) => `${docblock}${name}: ${c}; `)
2883
- ),
2884
- strictType: pipe24(
2885
- originalChildManifest.strictType,
2886
- (f) => mapFragmentContent11(f, (c) => `${docblock}${name}: ${c}; `)
2887
- )
2976
+ decoder: fragment`['${name}', ${originalChildManifest.decoder}]`,
2977
+ encoder: fragment`['${name}', ${originalChildManifest.encoder}]`,
2978
+ looseType: fragment`${docs}${name}: ${originalChildManifest.looseType}; `,
2979
+ strictType: fragment`${docs}${name}: ${originalChildManifest.strictType}; `
2888
2980
  });
2889
2981
  if (!structFieldType.defaultValue) {
2890
2982
  return childManifest;
@@ -2892,30 +2984,22 @@ ${jsDocblock(structFieldDocs)}` : "";
2892
2984
  if (structFieldType.defaultValueStrategy !== "omitted") {
2893
2985
  return typeManifest({
2894
2986
  ...childManifest,
2895
- looseType: pipe24(
2896
- childManifest.looseType,
2897
- (f) => setFragmentContent2(f, `${docblock}${name}?: ${originalLooseType}; `)
2898
- )
2987
+ looseType: fragment`${docs}${name}?: ${originalChildManifest.looseType}; `
2899
2988
  });
2900
2989
  }
2901
- return typeManifest({
2902
- ...childManifest,
2903
- looseType: fragment("")
2904
- });
2990
+ return typeManifest({ ...childManifest, looseType: fragment`` });
2905
2991
  },
2906
2992
  visitStructFieldValue(node, { self }) {
2993
+ const innerValue = visit8(node.value, self).value;
2907
2994
  return typeManifest({
2908
- value: pipe24(
2909
- visit5(node.value, self).value,
2910
- (f) => mapFragmentContent11(f, (c) => `${node.name}: ${c}`)
2911
- )
2995
+ value: fragment`${node.name}: ${innerValue}`
2912
2996
  });
2913
2997
  },
2914
2998
  visitStructType(structType, { self }) {
2915
2999
  const optionalFields = structType.fields.filter((f) => !!f.defaultValue);
2916
- const mergedManifest = pipe24(
3000
+ const mergedManifest = pipe15(
2917
3001
  mergeTypeManifests(
2918
- structType.fields.map((field) => visit5(field, self)),
3002
+ structType.fields.map((field) => visit8(field, self)),
2919
3003
  {
2920
3004
  mergeCodecs: (renders) => `([${renders.join(", ")}])`,
2921
3005
  mergeTypes: (renders) => `{ ${renders.join("")} }`
@@ -2923,16 +3007,8 @@ ${jsDocblock(structFieldDocs)}` : "";
2923
3007
  ),
2924
3008
  (manifest) => typeManifest({
2925
3009
  ...manifest,
2926
- decoder: pipe24(
2927
- manifest.decoder,
2928
- (f) => mapFragmentContent11(f, (c) => `getStructDecoder${c}`),
2929
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getStructDecoder"])
2930
- ),
2931
- encoder: pipe24(
2932
- manifest.encoder,
2933
- (f) => mapFragmentContent11(f, (c) => `getStructEncoder${c}`),
2934
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getStructEncoder"])
2935
- )
3010
+ decoder: fragment`${use("getStructDecoder", "solanaCodecsDataStructures")}${manifest.decoder}`,
3011
+ encoder: fragment`${use("getStructEncoder", "solanaCodecsDataStructures")}${manifest.encoder}`
2936
3012
  })
2937
3013
  );
2938
3014
  if (optionalFields.length === 0) {
@@ -2944,105 +3020,74 @@ ${jsDocblock(structFieldDocs)}` : "";
2944
3020
  const discriminatorPrefix = instructionNode ? instructionNode.name : accountNode?.name;
2945
3021
  const discriminators = (instructionNode ? instructionNode.discriminators : accountNode?.discriminators) ?? [];
2946
3022
  const fieldDiscriminators = discriminators.filter(isNodeFilter6("fieldDiscriminatorNode"));
2947
- const encoderImports = new ImportMap();
2948
- const defaultValues = optionalFields.map((f) => {
2949
- const key = camelCase10(f.name);
2950
- if (fieldDiscriminators.some((d) => d.name === f.name)) {
2951
- const constantName = nameApi.constant(camelCase10(`${discriminatorPrefix}_${f.name}`));
2952
- return f.defaultValueStrategy === "omitted" ? `${key}: ${constantName}` : `${key}: value.${key} ?? ${constantName}`;
2953
- }
2954
- const defaultValue = f.defaultValue;
2955
- const { content: renderedValue, imports } = visit5(defaultValue, self).value;
2956
- encoderImports.mergeWith(imports);
2957
- return f.defaultValueStrategy === "omitted" ? `${key}: ${renderedValue}` : `${key}: value.${key} ?? ${renderedValue}`;
2958
- }).join(", ");
3023
+ const defaultValues = mergeFragments(
3024
+ optionalFields.map((f) => {
3025
+ const key = camelCase13(f.name);
3026
+ if (fieldDiscriminators.some((d) => d.name === f.name)) {
3027
+ const constantName = nameApi.constant(camelCase13(`${discriminatorPrefix}_${f.name}`));
3028
+ return f.defaultValueStrategy === "omitted" ? fragment`${key}: ${constantName}` : fragment`${key}: value.${key} ?? ${constantName}`;
3029
+ }
3030
+ const defaultValue = f.defaultValue;
3031
+ const value = visit8(defaultValue, self).value;
3032
+ return f.defaultValueStrategy === "omitted" ? fragment`${key}: ${value}` : fragment`${key}: value.${key} ?? ${value}`;
3033
+ }),
3034
+ (cs) => cs.join(", ")
3035
+ );
2959
3036
  return typeManifest({
2960
3037
  ...mergedManifest,
2961
- encoder: pipe24(
2962
- mergedManifest.encoder,
2963
- (f) => mapFragmentContent11(
2964
- f,
2965
- (c) => `transformEncoder(${c}, (value) => ({ ...value, ${defaultValues} }))`
2966
- ),
2967
- (f) => addFragmentImports(f, "solanaCodecsCore", ["transformEncoder"]),
2968
- (f) => mergeFragmentImports(f, [encoderImports])
2969
- )
3038
+ encoder: fragment`${use("transformEncoder", "solanaCodecsCore")}(${mergedManifest.encoder}, (value) => ({ ...value, ${defaultValues} }))`
2970
3039
  });
2971
3040
  },
2972
3041
  visitStructValue(node, { self }) {
2973
3042
  return mergeTypeManifests(
2974
- node.fields.map((field) => visit5(field, self)),
3043
+ node.fields.map((field) => visit8(field, self)),
2975
3044
  { mergeValues: (renders) => `{ ${renders.join(", ")} }` }
2976
3045
  );
2977
3046
  },
2978
3047
  visitTupleType(tupleType, { self }) {
2979
- const items = tupleType.items.map((item) => visit5(item, self));
3048
+ const items = tupleType.items.map((item) => visit8(item, self));
2980
3049
  const mergedManifest = mergeTypeManifests(items, {
2981
3050
  mergeCodecs: (codecs) => `[${codecs.join(", ")}]`,
2982
3051
  mergeTypes: (types) => `readonly [${types.join(", ")}]`
2983
3052
  });
2984
3053
  return typeManifest({
2985
3054
  ...mergedManifest,
2986
- decoder: pipe24(
2987
- mergedManifest.decoder,
2988
- (f) => mapFragmentContent11(f, (c) => `getTupleDecoder(${c})`),
2989
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getTupleDecoder"])
2990
- ),
2991
- encoder: pipe24(
2992
- mergedManifest.encoder,
2993
- (f) => mapFragmentContent11(f, (c) => `getTupleEncoder(${c})`),
2994
- (f) => addFragmentImports(f, "solanaCodecsDataStructures", ["getTupleEncoder"])
2995
- )
3055
+ decoder: fragment`${use("getTupleDecoder", "solanaCodecsDataStructures")}(${mergedManifest.decoder})`,
3056
+ encoder: fragment`${use("getTupleEncoder", "solanaCodecsDataStructures")}(${mergedManifest.encoder})`
2996
3057
  });
2997
3058
  },
2998
3059
  visitTupleValue(node, { self }) {
2999
3060
  return mergeTypeManifests(
3000
- node.items.map((v) => visit5(v, self)),
3061
+ node.items.map((v) => visit8(v, self)),
3001
3062
  { mergeValues: (renders) => `[${renders.join(", ")}]` }
3002
3063
  );
3003
3064
  },
3004
3065
  visitZeroableOptionType(node, { self }) {
3005
- const childManifest = visit5(node.item, self);
3006
- const encoderOptions = ["prefix: null"];
3007
- const decoderOptions = ["prefix: null"];
3008
- const encoderImports = new ImportMap();
3009
- const decoderImports = new ImportMap();
3066
+ const childManifest = visit8(node.item, self);
3067
+ const encoderOptions = [fragment`prefix: null`];
3068
+ const decoderOptions = [fragment`prefix: null`];
3010
3069
  if (node.zeroValue) {
3011
- const zeroValueManifest = visit5(node.zeroValue, self);
3012
- encoderImports.mergeWith(zeroValueManifest.value);
3013
- decoderImports.mergeWith(zeroValueManifest.value);
3014
- encoderOptions.push(`noneValue: ${zeroValueManifest.value.content}`);
3015
- decoderOptions.push(`noneValue: ${zeroValueManifest.value.content}`);
3070
+ const zeroValueManifest = visit8(node.zeroValue, self);
3071
+ encoderOptions.push(fragment`noneValue: ${zeroValueManifest.value}`);
3072
+ decoderOptions.push(fragment`noneValue: ${zeroValueManifest.value}`);
3016
3073
  } else {
3017
- encoderOptions.push(`noneValue: "zeroes"`);
3018
- decoderOptions.push(`noneValue: "zeroes"`);
3074
+ encoderOptions.push(fragment`noneValue: "zeroes"`);
3075
+ decoderOptions.push(fragment`noneValue: "zeroes"`);
3019
3076
  }
3020
- const encoderOptionsAsString = encoderOptions.length > 0 ? `, { ${encoderOptions.join(", ")} }` : "";
3021
- const decoderOptionsAsString = decoderOptions.length > 0 ? `, { ${decoderOptions.join(", ")} }` : "";
3077
+ const encoderOptionsFragment = mergeFragments(
3078
+ encoderOptions,
3079
+ (cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
3080
+ );
3081
+ const decoderOptionsFragment = mergeFragments(
3082
+ decoderOptions,
3083
+ (cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
3084
+ );
3022
3085
  return typeManifest({
3023
3086
  ...childManifest,
3024
- decoder: pipe24(
3025
- childManifest.decoder,
3026
- (f) => mapFragmentContent11(f, (c) => `getOptionDecoder(${c + decoderOptionsAsString})`),
3027
- (f) => addFragmentImports(f, "solanaOptions", ["getOptionDecoder"]),
3028
- (f) => mergeFragmentImports(f, [decoderImports])
3029
- ),
3030
- encoder: pipe24(
3031
- childManifest.encoder,
3032
- (f) => mapFragmentContent11(f, (c) => `getOptionEncoder(${c + encoderOptionsAsString})`),
3033
- (f) => addFragmentImports(f, "solanaOptions", ["getOptionEncoder"]),
3034
- (f) => mergeFragmentImports(f, [encoderImports])
3035
- ),
3036
- looseType: pipe24(
3037
- childManifest.looseType,
3038
- (f) => mapFragmentContent11(f, (c) => `OptionOrNullable<${c}>`),
3039
- (f) => addFragmentImports(f, "solanaOptions", ["type OptionOrNullable"])
3040
- ),
3041
- strictType: pipe24(
3042
- childManifest.strictType,
3043
- (f) => mapFragmentContent11(f, (c) => `Option<${c}>`),
3044
- (f) => addFragmentImports(f, "solanaOptions", ["type Option"])
3045
- )
3087
+ decoder: fragment`${use("getOptionDecoder", "solanaOptions")}(${childManifest.decoder}${decoderOptionsFragment})`,
3088
+ encoder: fragment`${use("getOptionEncoder", "solanaOptions")}(${childManifest.encoder}${encoderOptionsFragment})`,
3089
+ looseType: fragment`${use("type OptionOrNullable", "solanaOptions")}<${childManifest.looseType}>`,
3090
+ strictType: fragment`${use("type Option", "solanaOptions")}<${childManifest.strictType}>`
3046
3091
  });
3047
3092
  }
3048
3093
  }),
@@ -3052,292 +3097,99 @@ ${jsDocblock(structFieldDocs)}` : "";
3052
3097
  function getArrayLikeSizeOption(count, visitor) {
3053
3098
  if (isNode15(count, "fixedCountNode")) {
3054
3099
  return {
3055
- decoder: fragment(`size: ${count.value}`),
3056
- encoder: fragment(`size: ${count.value}`)
3100
+ decoder: fragment`size: ${count.value}`,
3101
+ encoder: fragment`size: ${count.value}`
3057
3102
  };
3058
3103
  }
3059
3104
  if (isNode15(count, "remainderCountNode")) {
3060
3105
  return {
3061
- decoder: fragment(`size: 'remainder'`),
3062
- encoder: fragment(`size: 'remainder'`)
3106
+ decoder: fragment`size: 'remainder'`,
3107
+ encoder: fragment`size: 'remainder'`
3063
3108
  };
3064
3109
  }
3065
- const prefix = resolveNestedTypeNode3(count.prefix);
3110
+ const prefix = resolveNestedTypeNode4(count.prefix);
3066
3111
  if (prefix.format === "u32" && prefix.endian === "le") {
3067
- return { decoder: fragment(""), encoder: fragment("") };
3112
+ return { decoder: void 0, encoder: void 0 };
3068
3113
  }
3069
- const prefixManifest = visit5(count.prefix, visitor);
3114
+ const prefixManifest = visit8(count.prefix, visitor);
3070
3115
  return {
3071
- decoder: pipe24(prefixManifest.decoder, (f) => mapFragmentContent11(f, (c) => `size: ${c}`)),
3072
- encoder: pipe24(prefixManifest.encoder, (f) => mapFragmentContent11(f, (c) => `size: ${c}`))
3073
- };
3074
- }
3075
-
3076
- // src/nameTransformers.ts
3077
- import { camelCase as camelCase11, capitalize, kebabCase as kebabCase2, pascalCase as pascalCase7, snakeCase as snakeCase2, titleCase as titleCase2 } from "@codama/nodes";
3078
- function getNameApi(transformers) {
3079
- const helpers = {
3080
- camelCase: camelCase11,
3081
- capitalize,
3082
- kebabCase: kebabCase2,
3083
- pascalCase: pascalCase7,
3084
- snakeCase: snakeCase2,
3085
- titleCase: titleCase2
3116
+ decoder: pipe15(prefixManifest.decoder, (f) => mapFragmentContent11(f, (c) => `size: ${c}`)),
3117
+ encoder: pipe15(prefixManifest.encoder, (f) => mapFragmentContent11(f, (c) => `size: ${c}`))
3086
3118
  };
3087
- return Object.fromEntries(
3088
- Object.entries(transformers).map(([key, transformer]) => [key, (name) => transformer(name, helpers)])
3089
- );
3090
3119
  }
3091
- var DEFAULT_NAME_TRANSFORMERS = {
3092
- accountDecodeFunction: (name) => `decode${pascalCase7(name)}`,
3093
- accountFetchAllFunction: (name) => `fetchAll${pascalCase7(name)}`,
3094
- accountFetchAllMaybeFunction: (name) => `fetchAllMaybe${pascalCase7(name)}`,
3095
- accountFetchFromSeedsFunction: (name) => `fetch${pascalCase7(name)}FromSeeds`,
3096
- accountFetchFunction: (name) => `fetch${pascalCase7(name)}`,
3097
- accountFetchMaybeFromSeedsFunction: (name) => `fetchMaybe${pascalCase7(name)}FromSeeds`,
3098
- accountFetchMaybeFunction: (name) => `fetchMaybe${pascalCase7(name)}`,
3099
- accountGetSizeFunction: (name) => `get${pascalCase7(name)}Size`,
3100
- codecFunction: (name) => `get${pascalCase7(name)}Codec`,
3101
- constant: (name) => snakeCase2(name).toUpperCase(),
3102
- constantFunction: (name) => `get${pascalCase7(name)}Bytes`,
3103
- dataArgsType: (name) => `${pascalCase7(name)}Args`,
3104
- dataType: (name) => `${pascalCase7(name)}`,
3105
- decoderFunction: (name) => `get${pascalCase7(name)}Decoder`,
3106
- discriminatedUnionDiscriminator: () => "__kind",
3107
- discriminatedUnionFunction: (name) => `${camelCase11(name)}`,
3108
- discriminatedUnionVariant: (name) => `${pascalCase7(name)}`,
3109
- encoderFunction: (name) => `get${pascalCase7(name)}Encoder`,
3110
- enumVariant: (name) => `${pascalCase7(name)}`,
3111
- instructionAsyncFunction: (name) => `get${pascalCase7(name)}InstructionAsync`,
3112
- instructionAsyncInputType: (name) => `${pascalCase7(name)}AsyncInput`,
3113
- instructionDataType: (name) => `${pascalCase7(name)}InstructionData`,
3114
- instructionExtraType: (name) => `${pascalCase7(name)}InstructionExtra`,
3115
- instructionParseFunction: (name) => `parse${pascalCase7(name)}Instruction`,
3116
- instructionParsedType: (name) => `Parsed${pascalCase7(name)}Instruction`,
3117
- instructionSyncFunction: (name) => `get${pascalCase7(name)}Instruction`,
3118
- instructionSyncInputType: (name) => `${pascalCase7(name)}Input`,
3119
- instructionType: (name) => `${pascalCase7(name)}Instruction`,
3120
- isDiscriminatedUnionFunction: (name) => `is${pascalCase7(name)}`,
3121
- pdaFindFunction: (name) => `find${pascalCase7(name)}Pda`,
3122
- pdaSeedsType: (name) => `${pascalCase7(name)}Seeds`,
3123
- programAccountsEnum: (name) => `${pascalCase7(name)}Account`,
3124
- programAccountsEnumVariant: (name) => `${pascalCase7(name)}`,
3125
- programAccountsIdentifierFunction: (name) => `identify${pascalCase7(name)}Account`,
3126
- programAddressConstant: (name) => `${snakeCase2(name).toUpperCase()}_PROGRAM_ADDRESS`,
3127
- programErrorConstant: (name) => snakeCase2(name).toUpperCase(),
3128
- programErrorConstantPrefix: (name) => `${snakeCase2(name).toUpperCase()}_ERROR__`,
3129
- programErrorMessagesMap: (name) => `${camelCase11(name)}ErrorMessages`,
3130
- programErrorUnion: (name) => `${pascalCase7(name)}Error`,
3131
- programGetErrorMessageFunction: (name) => `get${pascalCase7(name)}ErrorMessage`,
3132
- programInstructionsEnum: (name) => `${pascalCase7(name)}Instruction`,
3133
- programInstructionsEnumVariant: (name) => `${pascalCase7(name)}`,
3134
- programInstructionsIdentifierFunction: (name) => `identify${pascalCase7(name)}Instruction`,
3135
- programInstructionsParsedUnionType: (name) => `Parsed${pascalCase7(name)}Instruction`,
3136
- programIsErrorFunction: (name) => `is${pascalCase7(name)}Error`,
3137
- resolverFunction: (name) => `${camelCase11(name)}`
3138
- };
3139
3120
 
3140
- // src/getRenderMapVisitor.ts
3121
+ // src/visitors/getRenderMapVisitor.ts
3141
3122
  function getRenderMapVisitor(options = {}) {
3142
3123
  const linkables = new LinkableDictionary3();
3143
3124
  const stack = new NodeStack2();
3144
- const nameTransformers = {
3145
- ...DEFAULT_NAME_TRANSFORMERS,
3146
- ...options.nameTransformers
3147
- };
3148
- const nameApi = getNameApi(nameTransformers);
3149
- const renderParentInstructions = options.renderParentInstructions ?? false;
3150
- const dependencyMap = options.dependencyMap ?? {};
3151
- const useGranularImports = options.useGranularImports ?? false;
3152
- const asyncResolvers = (options.asyncResolvers ?? []).map(camelCase12);
3153
- const nonScalarEnums = (options.nonScalarEnums ?? []).map(camelCase12);
3154
- const internalNodes = (options.internalNodes ?? []).map(camelCase12);
3155
3125
  const customAccountData = parseCustomDataOptions(options.customAccountData ?? [], "AccountData");
3156
3126
  const customInstructionData = parseCustomDataOptions(options.customInstructionData ?? [], "InstructionData");
3157
- const getImportFrom = getImportFromFactory(options.linkOverrides ?? {}, customAccountData, customInstructionData);
3158
- const typeManifestVisitor = getTypeManifestVisitor({
3127
+ const renderScopeWithTypeManifestVisitor = {
3128
+ asyncResolvers: (options.asyncResolvers ?? []).map(camelCase14),
3159
3129
  customAccountData,
3160
3130
  customInstructionData,
3161
- getImportFrom,
3131
+ dependencyMap: options.dependencyMap ?? {},
3132
+ getImportFrom: getImportFromFactory(options.linkOverrides ?? {}, customAccountData, customInstructionData),
3162
3133
  linkables,
3163
- nameApi,
3164
- nonScalarEnums,
3165
- stack
3166
- });
3134
+ nameApi: getNameApi({ ...DEFAULT_NAME_TRANSFORMERS, ...options.nameTransformers }),
3135
+ nonScalarEnums: (options.nonScalarEnums ?? []).map(camelCase14),
3136
+ renderParentInstructions: options.renderParentInstructions ?? false,
3137
+ useGranularImports: options.useGranularImports ?? false
3138
+ };
3139
+ const typeManifestVisitor = getTypeManifestVisitor({ ...renderScopeWithTypeManifestVisitor, stack });
3140
+ const renderScope = { ...renderScopeWithTypeManifestVisitor, typeManifestVisitor };
3141
+ const internalNodes = (options.internalNodes ?? []).map(camelCase14);
3167
3142
  const resolvedInstructionInputVisitor = getResolvedInstructionInputsVisitor();
3168
3143
  const byteSizeVisitor = getByteSizeVisitor(linkables, { stack });
3169
- const globalScope = {
3170
- asyncResolvers,
3171
- customAccountData,
3172
- customInstructionData,
3173
- getImportFrom,
3174
- linkables,
3175
- nameApi,
3176
- nonScalarEnums,
3177
- renderParentInstructions,
3178
- typeManifestVisitor
3179
- };
3180
- const render2 = (template, context, renderOptions) => {
3181
- return render(join2("pages", template), context, renderOptions);
3144
+ const asPage = (fragment2, dependencyMap = {}) => {
3145
+ if (!fragment2) return void 0;
3146
+ return getPageFragment(fragment2, {
3147
+ ...renderScope,
3148
+ dependencyMap: { ...renderScope.dependencyMap, ...dependencyMap }
3149
+ });
3182
3150
  };
3183
- return pipe25(
3184
- staticVisitor2(() => renderMap(), {
3151
+ return pipe16(
3152
+ staticVisitor2(() => createRenderMap(), {
3185
3153
  keys: ["rootNode", "programNode", "pdaNode", "accountNode", "definedTypeNode", "instructionNode"]
3186
3154
  }),
3187
3155
  (v) => extendVisitor2(v, {
3188
3156
  visitAccount(node) {
3189
- const accountPath = stack.getPath("accountNode");
3190
- if (!findProgramNodeFromPath7(accountPath)) {
3191
- throw new Error("Account must be visited inside a program.");
3192
- }
3193
- const scope = {
3194
- ...globalScope,
3195
- accountPath,
3196
- size: visit6(node, byteSizeVisitor),
3197
- typeManifest: visit6(node, typeManifestVisitor)
3198
- };
3199
- const fields = resolveNestedTypeNode4(node.data).fields;
3200
- const accountDiscriminatorConstantsFragment = getDiscriminatorConstantsFragment({
3201
- ...scope,
3202
- discriminatorNodes: node.discriminators ?? [],
3203
- fields,
3204
- prefix: node.name
3205
- });
3206
- const accountTypeFragment = getAccountTypeFragment(scope);
3207
- const accountFetchHelpersFragment = getAccountFetchHelpersFragment(scope);
3208
- const accountSizeHelpersFragment = getAccountSizeHelpersFragment(scope);
3209
- const accountPdaHelpersFragment = getAccountPdaHelpersFragment(scope);
3210
- const imports = new ImportMap().mergeWith(
3211
- accountDiscriminatorConstantsFragment,
3212
- accountTypeFragment,
3213
- accountFetchHelpersFragment,
3214
- accountSizeHelpersFragment,
3215
- accountPdaHelpersFragment
3216
- );
3217
- return addToRenderMap(
3218
- renderMap(),
3219
- `accounts/${camelCase12(node.name)}.ts`,
3220
- render2("accountsPage.njk", {
3221
- accountDiscriminatorConstantsFragment: accountDiscriminatorConstantsFragment.content,
3222
- accountFetchHelpersFragment: accountFetchHelpersFragment.content,
3223
- accountPdaHelpersFragment: accountPdaHelpersFragment.content,
3224
- accountSizeHelpersFragment: accountSizeHelpersFragment.content,
3225
- accountTypeFragment: accountTypeFragment.content,
3226
- imports: imports.toString(dependencyMap, useGranularImports)
3227
- })
3157
+ return createRenderMap(
3158
+ `accounts/${camelCase14(node.name)}.ts`,
3159
+ asPage(
3160
+ getAccountPageFragment({
3161
+ ...renderScope,
3162
+ accountPath: stack.getPath("accountNode"),
3163
+ size: visit9(node, byteSizeVisitor)
3164
+ })
3165
+ )
3228
3166
  );
3229
3167
  },
3230
3168
  visitDefinedType(node) {
3231
- const scope = {
3232
- ...globalScope,
3233
- codecDocs: [],
3234
- decoderDocs: [],
3235
- encoderDocs: [],
3236
- manifest: visit6(node, typeManifestVisitor),
3237
- name: node.name,
3238
- node: node.type,
3239
- size: visit6(node, byteSizeVisitor),
3240
- typeDocs: node.docs,
3241
- typeNode: node.type
3242
- };
3243
- const typeWithCodecFragment = getTypeWithCodecFragment(scope);
3244
- const typeDiscriminatedUnionHelpersFragment = getTypeDiscriminatedUnionHelpersFragment(scope);
3245
- const imports = new ImportMap().mergeWith(typeWithCodecFragment, typeDiscriminatedUnionHelpersFragment).remove("generatedTypes", [
3246
- nameApi.dataType(node.name),
3247
- nameApi.dataArgsType(node.name),
3248
- nameApi.encoderFunction(node.name),
3249
- nameApi.decoderFunction(node.name),
3250
- nameApi.codecFunction(node.name)
3251
- ]);
3252
- return addToRenderMap(
3253
- renderMap(),
3254
- `types/${camelCase12(node.name)}.ts`,
3255
- render2("definedTypesPage.njk", {
3256
- imports: imports.toString({ ...dependencyMap, generatedTypes: "." }),
3257
- typeDiscriminatedUnionHelpersFragment: typeDiscriminatedUnionHelpersFragment.content,
3258
- typeWithCodecFragment: typeWithCodecFragment.content
3169
+ return createRenderMap(
3170
+ `types/${camelCase14(node.name)}.ts`,
3171
+ asPage(getTypePageFragment({ ...renderScope, node, size: visit9(node, byteSizeVisitor) }), {
3172
+ generatedTypes: "."
3259
3173
  })
3260
3174
  );
3261
3175
  },
3262
3176
  visitInstruction(node) {
3263
- const instructionPath = stack.getPath("instructionNode");
3264
- if (!findProgramNodeFromPath7(instructionPath)) {
3265
- throw new Error("Instruction must be visited inside a program.");
3266
- }
3267
- const instructionExtraName = nameApi.instructionExtraType(node.name);
3268
- const scope = {
3269
- ...globalScope,
3270
- dataArgsManifest: visit6(node, typeManifestVisitor),
3271
- extraArgsManifest: visit6(
3272
- definedTypeNode2({
3273
- name: instructionExtraName,
3274
- type: structTypeNodeFromInstructionArgumentNodes5(node.extraArguments ?? [])
3275
- }),
3276
- typeManifestVisitor
3277
- ),
3278
- instructionPath,
3279
- renamedArgs: getRenamedArgsMap(node),
3280
- resolvedInputs: visit6(node, resolvedInstructionInputVisitor),
3281
- size: visit6(node, byteSizeVisitor)
3282
- };
3283
- const instructionDiscriminatorConstantsFragment = getDiscriminatorConstantsFragment({
3284
- ...scope,
3285
- discriminatorNodes: node.discriminators ?? [],
3286
- fields: node.arguments,
3287
- prefix: node.name
3288
- });
3289
- const instructionTypeFragment = getInstructionTypeFragment(scope);
3290
- const instructionDataFragment = getInstructionDataFragment(scope);
3291
- const instructionExtraArgsFragment = getInstructionExtraArgsFragment(scope);
3292
- const instructionFunctionAsyncFragment = getInstructionFunctionFragment({
3293
- ...scope,
3294
- useAsync: true
3295
- });
3296
- const instructionFunctionSyncFragment = getInstructionFunctionFragment({
3297
- ...scope,
3298
- useAsync: false
3299
- });
3300
- const instructionParseFunctionFragment = getInstructionParseFunctionFragment(scope);
3301
- const imports = new ImportMap().mergeWith(
3302
- instructionDiscriminatorConstantsFragment,
3303
- instructionTypeFragment,
3304
- instructionDataFragment,
3305
- instructionExtraArgsFragment,
3306
- instructionFunctionAsyncFragment,
3307
- instructionFunctionSyncFragment,
3308
- instructionParseFunctionFragment
3309
- );
3310
- return addToRenderMap(
3311
- renderMap(),
3312
- `instructions/${camelCase12(node.name)}.ts`,
3313
- render2("instructionsPage.njk", {
3314
- imports: imports.toString(dependencyMap, useGranularImports),
3315
- instruction: node,
3316
- instructionDataFragment: instructionDataFragment.content,
3317
- instructionDiscriminatorConstantsFragment: instructionDiscriminatorConstantsFragment.content,
3318
- instructionExtraArgsFragment: instructionExtraArgsFragment.content,
3319
- instructionFunctionAsyncFragment: instructionFunctionAsyncFragment.content,
3320
- instructionFunctionSyncFragment: instructionFunctionSyncFragment.content,
3321
- instructionParseFunctionFragment: instructionParseFunctionFragment.content,
3322
- instructionTypeFragment: instructionTypeFragment.content
3323
- })
3177
+ return createRenderMap(
3178
+ `instructions/${camelCase14(node.name)}.ts`,
3179
+ asPage(
3180
+ getInstructionPageFragment({
3181
+ ...renderScope,
3182
+ instructionPath: stack.getPath("instructionNode"),
3183
+ resolvedInputs: visit9(node, resolvedInstructionInputVisitor),
3184
+ size: visit9(node, byteSizeVisitor)
3185
+ })
3186
+ )
3324
3187
  );
3325
3188
  },
3326
3189
  visitPda(node) {
3327
- const pdaPath = stack.getPath("pdaNode");
3328
- if (!findProgramNodeFromPath7(pdaPath)) {
3329
- throw new Error("PDA must be visited inside a program.");
3330
- }
3331
- const scope = { ...globalScope, pdaPath };
3332
- const pdaFunctionFragment = getPdaFunctionFragment(scope);
3333
- const imports = new ImportMap().mergeWith(pdaFunctionFragment);
3334
- return addToRenderMap(
3335
- renderMap(),
3336
- `pdas/${camelCase12(node.name)}.ts`,
3337
- render2("pdasPage.njk", {
3338
- imports: imports.toString(dependencyMap, useGranularImports),
3339
- pdaFunctionFragment: pdaFunctionFragment.content
3340
- })
3190
+ return createRenderMap(
3191
+ `pdas/${camelCase14(node.name)}.ts`,
3192
+ asPage(getPdaPageFragment({ ...renderScope, pdaPath: stack.getPath("pdaNode") }))
3341
3193
  );
3342
3194
  },
3343
3195
  visitProgram(node, { self }) {
@@ -3345,42 +3197,19 @@ function getRenderMapVisitor(options = {}) {
3345
3197
  ...getDefinedTypeNodesToExtract(node.accounts, customAccountData),
3346
3198
  ...getDefinedTypeNodesToExtract(node.instructions, customInstructionData)
3347
3199
  ];
3348
- const scope = { ...globalScope, programNode: node };
3349
- let renders = mergeRenderMaps([
3350
- ...node.pdas.map((p) => visit6(p, self)),
3351
- ...node.accounts.map((a) => visit6(a, self)),
3352
- ...node.definedTypes.map((t) => visit6(t, self)),
3353
- ...customDataDefinedType.map((t) => visit6(t, self))
3354
- ]);
3355
- if (node.errors.length > 0) {
3356
- const programErrorsFragment = getProgramErrorsFragment(scope);
3357
- renders = addToRenderMap(
3358
- renders,
3359
- `errors/${camelCase12(node.name)}.ts`,
3360
- render2("errorsPage.njk", {
3361
- imports: new ImportMap().mergeWith(programErrorsFragment).toString(dependencyMap, useGranularImports),
3362
- programErrorsFragment: programErrorsFragment.content
3363
- })
3364
- );
3365
- }
3366
- const programFragment = getProgramFragment(scope);
3367
- const programAccountsFragment = getProgramAccountsFragment(scope);
3368
- const programInstructionsFragment = getProgramInstructionsFragment(scope);
3369
- renders = addToRenderMap(
3370
- renders,
3371
- `programs/${camelCase12(node.name)}.ts`,
3372
- render2("programsPage.njk", {
3373
- imports: new ImportMap().mergeWith(programFragment, programAccountsFragment, programInstructionsFragment).toString(dependencyMap, useGranularImports),
3374
- programAccountsFragment: programAccountsFragment.content,
3375
- programFragment: programFragment.content,
3376
- programInstructionsFragment: programInstructionsFragment.content
3377
- })
3378
- );
3200
+ const scope = { ...renderScope, programNode: node };
3379
3201
  return mergeRenderMaps([
3380
- renders,
3381
- ...getAllInstructionsWithSubs2(node, {
3382
- leavesOnly: !renderParentInstructions
3383
- }).map((ix) => visit6(ix, self))
3202
+ createRenderMap({
3203
+ [`programs/${camelCase14(node.name)}.ts`]: asPage(getProgramPageFragment(scope)),
3204
+ [`errors/${camelCase14(node.name)}.ts`]: node.errors.length > 0 ? asPage(getErrorPageFragment(scope)) : void 0
3205
+ }),
3206
+ ...node.pdas.map((p) => visit9(p, self)),
3207
+ ...node.accounts.map((a) => visit9(a, self)),
3208
+ ...node.definedTypes.map((t) => visit9(t, self)),
3209
+ ...customDataDefinedType.map((t) => visit9(t, self)),
3210
+ ...getAllInstructionsWithSubs2(node, { leavesOnly: !renderScope.renderParentInstructions }).map(
3211
+ (i) => visit9(i, self)
3212
+ )
3384
3213
  ]);
3385
3214
  },
3386
3215
  visitRoot(node, { self }) {
@@ -3390,97 +3219,41 @@ function getRenderMapVisitor(options = {}) {
3390
3219
  const pdasToExport = getAllPdas(node);
3391
3220
  const accountsToExport = getAllAccounts(node).filter(isNotInternal);
3392
3221
  const instructionsToExport = getAllInstructionsWithSubs2(node, {
3393
- leavesOnly: !renderParentInstructions
3222
+ leavesOnly: !renderScope.renderParentInstructions
3394
3223
  }).filter(isNotInternal);
3395
3224
  const definedTypesToExport = getAllDefinedTypes(node).filter(isNotInternal);
3396
3225
  const hasAnythingToExport = programsToExport.length > 0 || accountsToExport.length > 0 || instructionsToExport.length > 0 || definedTypesToExport.length > 0;
3397
- const ctx = {
3226
+ const scope = {
3227
+ ...renderScope,
3398
3228
  accountsToExport,
3399
3229
  definedTypesToExport,
3400
- hasAnythingToExport,
3401
3230
  instructionsToExport,
3402
3231
  pdasToExport,
3403
- programsToExport,
3404
- programsWithErrorsToExport,
3405
- root: node
3232
+ programsToExport
3406
3233
  };
3407
- let renders = renderMap();
3408
- if (hasAnythingToExport) {
3409
- renders = addToRenderMap(
3410
- renders,
3411
- "shared/index.ts",
3412
- render2("sharedPage.njk", {
3413
- ...ctx,
3414
- imports: new ImportMap().add("solanaAddresses", [
3415
- "type Address",
3416
- "isProgramDerivedAddress",
3417
- "type ProgramDerivedAddress"
3418
- ]).add("solanaInstructions", [
3419
- "AccountRole",
3420
- "type AccountMeta",
3421
- "upgradeRoleToSigner"
3422
- ]).add("solanaSigners", [
3423
- "type AccountSignerMeta",
3424
- "isTransactionSigner",
3425
- "type TransactionSigner"
3426
- ]).addAlias("solanaSigners", "isTransactionSigner", "kitIsTransactionSigner").toString(dependencyMap, useGranularImports)
3427
- })
3428
- );
3429
- }
3430
- if (programsToExport.length > 0) {
3431
- renders = addToRenderMap(renders, "programs/index.ts", render2("programsIndex.njk", ctx));
3432
- }
3433
- if (programsWithErrorsToExport.length > 0) {
3434
- renders = addToRenderMap(renders, "errors/index.ts", render2("errorsIndex.njk", ctx));
3435
- }
3436
- if (accountsToExport.length > 0) {
3437
- renders = addToRenderMap(renders, "accounts/index.ts", render2("accountsIndex.njk", ctx));
3438
- }
3439
- if (pdasToExport.length > 0) {
3440
- renders = addToRenderMap(renders, "pdas/index.ts", render2("pdasIndex.njk", ctx));
3441
- }
3442
- if (instructionsToExport.length > 0) {
3443
- renders = addToRenderMap(
3444
- renders,
3445
- "instructions/index.ts",
3446
- render2("instructionsIndex.njk", ctx)
3447
- );
3448
- }
3449
- if (definedTypesToExport.length > 0) {
3450
- renders = addToRenderMap(renders, "types/index.ts", render2("definedTypesIndex.njk", ctx));
3451
- }
3452
- return pipe25(
3453
- renders,
3454
- (r) => addToRenderMap(r, "index.ts", render2("rootIndex.njk", ctx)),
3455
- (r) => mergeRenderMaps([r, ...getAllPrograms(node).map((p) => visit6(p, self))])
3456
- );
3234
+ return mergeRenderMaps([
3235
+ createRenderMap({
3236
+ ["accounts/index.ts"]: asPage(getIndexPageFragment(accountsToExport)),
3237
+ ["errors/index.ts"]: asPage(getIndexPageFragment(programsWithErrorsToExport)),
3238
+ ["index.ts"]: asPage(getRootIndexPageFragment(scope)),
3239
+ ["instructions/index.ts"]: asPage(getIndexPageFragment(instructionsToExport)),
3240
+ ["pdas/index.ts"]: asPage(getIndexPageFragment(pdasToExport)),
3241
+ ["programs/index.ts"]: asPage(getIndexPageFragment(programsToExport)),
3242
+ ["shared/index.ts"]: hasAnythingToExport ? asPage(getSharedPageFragment()) : void 0,
3243
+ ["types/index.ts"]: asPage(getIndexPageFragment(definedTypesToExport))
3244
+ }),
3245
+ ...getAllPrograms(node).map((p) => visit9(p, self))
3246
+ ]);
3457
3247
  }
3458
3248
  }),
3459
3249
  (v) => recordNodeStackVisitor2(v, stack),
3460
3250
  (v) => recordLinkablesOnFirstVisitVisitor(v, linkables)
3461
3251
  );
3462
3252
  }
3463
- function getRenamedArgsMap(instruction) {
3464
- const argNames = [
3465
- ...instruction.arguments.map((a) => a.name),
3466
- ...(instruction.extraArguments ?? []).map((a) => a.name)
3467
- ];
3468
- const duplicateArgs = argNames.filter((e, i, a) => a.indexOf(e) !== i);
3469
- if (duplicateArgs.length > 0) {
3470
- throw new Error(`Duplicate args found: [${duplicateArgs.join(", ")}] in instruction [${instruction.name}].`);
3471
- }
3472
- const allNames = [...instruction.accounts.map((account) => account.name), ...argNames];
3473
- const duplicates = allNames.filter((e, i, a) => a.indexOf(e) !== i);
3474
- if (duplicates.length === 0) return /* @__PURE__ */ new Map();
3475
- logWarn(
3476
- `[JavaScript] Accounts and args of instruction [${instruction.name}] have the following conflicting attributes [${duplicates.join(", ")}]. Thus, the arguments have been renamed to avoid conflicts in the input type.`
3477
- );
3478
- return new Map(duplicates.map((name) => [camelCase12(name), camelCase12(`${name}Arg`)]));
3479
- }
3480
3253
 
3481
- // src/renderVisitor.ts
3254
+ // src/visitors/renderVisitor.ts
3482
3255
  import { deleteDirectory, mapRenderMapContentAsync, writeRenderMap } from "@codama/renderers-core";
3483
- import { rootNodeVisitor, visit as visit7 } from "@codama/visitors-core";
3256
+ import { rootNodeVisitor, visit as visit10 } from "@codama/visitors-core";
3484
3257
  import * as estreePlugin from "prettier/plugins/estree";
3485
3258
  import * as typeScriptPlugin from "prettier/plugins/typescript";
3486
3259
  import { format } from "prettier/standalone";
@@ -3500,22 +3273,27 @@ function renderVisitor(path, options = {}) {
3500
3273
  if (options.deleteFolderBeforeRendering ?? true) {
3501
3274
  deleteDirectory(path);
3502
3275
  }
3503
- let renderMap2 = visit7(root, getRenderMapVisitor(options));
3276
+ let renderMap = visit10(root, getRenderMapVisitor(options));
3504
3277
  if (options.formatCode ?? true) {
3505
3278
  const prettierOptions = { ...DEFAULT_PRETTIER_OPTIONS, ...options.prettierOptions };
3506
- renderMap2 = await mapRenderMapContentAsync(renderMap2, (code) => format(code, prettierOptions));
3279
+ renderMap = await mapRenderMapContentAsync(renderMap, (code) => format(code, prettierOptions));
3507
3280
  }
3508
- writeRenderMap(renderMap2, path);
3281
+ writeRenderMap(renderMap, path);
3509
3282
  });
3510
3283
  }
3511
3284
  export {
3512
3285
  DEFAULT_NAME_TRANSFORMERS,
3513
- ImportMap,
3286
+ addToImportMap,
3287
+ createImportMap,
3514
3288
  renderVisitor as default,
3515
3289
  getNameApi,
3516
3290
  getRenderMapVisitor,
3517
3291
  getTypeManifestVisitor,
3292
+ importMapToString,
3293
+ mergeImportMaps,
3518
3294
  mergeTypeManifests,
3295
+ parseImportInput,
3296
+ removeFromImportMap,
3519
3297
  renderVisitor,
3520
3298
  typeManifest
3521
3299
  };