@codama/renderers-js
Version:
JavaScript renderer compatible with the Solana Kit library
1,062 lines (1,025 loc) • 162 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
DEFAULT_NAME_TRANSFORMERS: () => DEFAULT_NAME_TRANSFORMERS,
addToImportMap: () => addToImportMap,
createImportMap: () => createImportMap,
default: () => renderVisitor,
getNameApi: () => getNameApi,
getRenderMapVisitor: () => getRenderMapVisitor,
getTypeManifestVisitor: () => getTypeManifestVisitor,
importMapToString: () => importMapToString,
mergeImportMaps: () => mergeImportMaps,
mergeTypeManifests: () => mergeTypeManifests,
parseImportInput: () => parseImportInput,
removeFromImportMap: () => removeFromImportMap,
renderVisitor: () => renderVisitor,
typeManifest: () => typeManifest
});
module.exports = __toCommonJS(index_exports);
// src/utils/importMap.ts
var DEFAULT_EXTERNAL_MODULE_MAP = {
solanaAccounts: "@solana/kit",
solanaAddresses: "@solana/kit",
solanaCodecsCore: "@solana/kit",
solanaCodecsDataStructures: "@solana/kit",
solanaCodecsNumbers: "@solana/kit",
solanaCodecsStrings: "@solana/kit",
solanaErrors: "@solana/kit",
solanaInstructions: "@solana/kit",
solanaOptions: "@solana/kit",
solanaPrograms: "@solana/kit",
solanaRpcTypes: "@solana/kit",
solanaSigners: "@solana/kit"
};
var DEFAULT_GRANULAR_EXTERNAL_MODULE_MAP = {
solanaAccounts: "@solana/accounts",
solanaAddresses: "@solana/addresses",
solanaCodecsCore: "@solana/codecs",
solanaCodecsDataStructures: "@solana/codecs",
solanaCodecsNumbers: "@solana/codecs",
solanaCodecsStrings: "@solana/codecs",
solanaErrors: "@solana/errors",
solanaInstructions: "@solana/instructions",
solanaOptions: "@solana/codecs",
solanaPrograms: "@solana/programs",
solanaRpcTypes: "@solana/rpc-types",
solanaSigners: "@solana/signers"
};
var DEFAULT_INTERNAL_MODULE_MAP = {
errors: "../errors",
generated: "..",
generatedAccounts: "../accounts",
generatedErrors: "../errors",
generatedInstructions: "../instructions",
generatedPdas: "../pdas",
generatedPrograms: "../programs",
generatedTypes: "../types",
hooked: "../../hooked",
shared: "../shared",
types: "../types"
};
function createImportMap() {
return Object.freeze(/* @__PURE__ */ new Map());
}
function parseImportInput(input) {
const matches = input.match(/^(type )?([^ ]+)(?: as (.+))?$/);
if (!matches) return Object.freeze({ importedIdentifier: input, isType: false, usedIdentifier: input });
const [_, isType, name, alias] = matches;
return Object.freeze({
importedIdentifier: name,
isType: !!isType,
usedIdentifier: alias ?? name
});
}
function addToImportMap(importMap, module2, imports) {
const parsedImports = imports.map(parseImportInput).map((i) => [i.usedIdentifier, i]);
return mergeImportMaps([importMap, /* @__PURE__ */ new Map([[module2, new Map(parsedImports)]])]);
}
function removeFromImportMap(importMap, module2, usedIdentifiers) {
const newMap = new Map(importMap);
const newModuleMap = new Map(newMap.get(module2));
usedIdentifiers.forEach((usedIdentifier) => {
newModuleMap.delete(usedIdentifier);
});
if (newModuleMap.size === 0) {
newMap.delete(module2);
} else {
newMap.set(module2, newModuleMap);
}
return Object.freeze(newMap);
}
function mergeImportMaps(importMaps) {
if (importMaps.length === 0) return createImportMap();
if (importMaps.length === 1) return importMaps[0];
const mergedMap = new Map(importMaps[0]);
for (const map of importMaps.slice(1)) {
for (const [module2, imports] of map) {
const mergedModuleMap = mergedMap.get(module2) ?? /* @__PURE__ */ new Map();
for (const [usedIdentifier, importInfo] of imports) {
const existingImportInfo = mergedModuleMap.get(usedIdentifier);
const shouldOverwriteTypeOnly = existingImportInfo && existingImportInfo.importedIdentifier === importInfo.importedIdentifier && existingImportInfo.isType && !importInfo.isType;
if (!existingImportInfo || shouldOverwriteTypeOnly) {
mergedModuleMap.set(usedIdentifier, importInfo);
}
}
mergedMap.set(module2, mergedModuleMap);
}
}
return Object.freeze(mergedMap);
}
function importMapToString(importMap, dependencyMap = {}, useGranularImports = false) {
const resolvedMap = resolveImportMapModules(importMap, dependencyMap, useGranularImports);
return [...resolvedMap.entries()].sort(([a], [b]) => {
const relative = Number(a.startsWith(".")) - Number(b.startsWith("."));
if (relative !== 0) return relative;
return a.localeCompare(b);
}).map(([module2, imports]) => {
const innerImports = [...imports.values()].map(importInfoToString).sort((a, b) => a.localeCompare(b)).join(", ");
return `import { ${innerImports} } from '${module2}';`;
}).join("\n");
}
function resolveImportMapModules(importMap, dependencyMap, useGranularImports) {
const dependencyMapWithDefaults = {
...useGranularImports ? DEFAULT_GRANULAR_EXTERNAL_MODULE_MAP : DEFAULT_EXTERNAL_MODULE_MAP,
...DEFAULT_INTERNAL_MODULE_MAP,
...dependencyMap
};
return mergeImportMaps(
[...importMap.entries()].map(([module2, imports]) => {
const resolvedModule = dependencyMapWithDefaults[module2] ?? module2;
return /* @__PURE__ */ new Map([[resolvedModule, imports]]);
})
);
}
function importInfoToString({ importedIdentifier, isType, usedIdentifier }) {
const alias = importedIdentifier !== usedIdentifier ? ` as ${usedIdentifier}` : "";
return `${isType ? "type " : ""}${importedIdentifier}${alias}`;
}
// src/utils/nameTransformers.ts
var import_nodes = require("@codama/nodes");
function getNameApi(transformers) {
const helpers = {
camelCase: import_nodes.camelCase,
capitalize: import_nodes.capitalize,
kebabCase: import_nodes.kebabCase,
pascalCase: import_nodes.pascalCase,
snakeCase: import_nodes.snakeCase,
titleCase: import_nodes.titleCase
};
return Object.fromEntries(
Object.entries(transformers).map(([key, transformer]) => [key, (name) => transformer(name, helpers)])
);
}
var DEFAULT_NAME_TRANSFORMERS = {
accountDecodeFunction: (name) => `decode${(0, import_nodes.pascalCase)(name)}`,
accountFetchAllFunction: (name) => `fetchAll${(0, import_nodes.pascalCase)(name)}`,
accountFetchAllMaybeFunction: (name) => `fetchAllMaybe${(0, import_nodes.pascalCase)(name)}`,
accountFetchFromSeedsFunction: (name) => `fetch${(0, import_nodes.pascalCase)(name)}FromSeeds`,
accountFetchFunction: (name) => `fetch${(0, import_nodes.pascalCase)(name)}`,
accountFetchMaybeFromSeedsFunction: (name) => `fetchMaybe${(0, import_nodes.pascalCase)(name)}FromSeeds`,
accountFetchMaybeFunction: (name) => `fetchMaybe${(0, import_nodes.pascalCase)(name)}`,
accountGetSizeFunction: (name) => `get${(0, import_nodes.pascalCase)(name)}Size`,
codecFunction: (name) => `get${(0, import_nodes.pascalCase)(name)}Codec`,
constant: (name) => (0, import_nodes.snakeCase)(name).toUpperCase(),
constantFunction: (name) => `get${(0, import_nodes.pascalCase)(name)}Bytes`,
dataArgsType: (name) => `${(0, import_nodes.pascalCase)(name)}Args`,
dataType: (name) => `${(0, import_nodes.pascalCase)(name)}`,
decoderFunction: (name) => `get${(0, import_nodes.pascalCase)(name)}Decoder`,
discriminatedUnionDiscriminator: () => "__kind",
discriminatedUnionFunction: (name) => `${(0, import_nodes.camelCase)(name)}`,
discriminatedUnionVariant: (name) => `${(0, import_nodes.pascalCase)(name)}`,
encoderFunction: (name) => `get${(0, import_nodes.pascalCase)(name)}Encoder`,
enumVariant: (name) => `${(0, import_nodes.pascalCase)(name)}`,
instructionAsyncFunction: (name) => `get${(0, import_nodes.pascalCase)(name)}InstructionAsync`,
instructionAsyncInputType: (name) => `${(0, import_nodes.pascalCase)(name)}AsyncInput`,
instructionDataType: (name) => `${(0, import_nodes.pascalCase)(name)}InstructionData`,
instructionExtraType: (name) => `${(0, import_nodes.pascalCase)(name)}InstructionExtra`,
instructionParseFunction: (name) => `parse${(0, import_nodes.pascalCase)(name)}Instruction`,
instructionParsedType: (name) => `Parsed${(0, import_nodes.pascalCase)(name)}Instruction`,
instructionSyncFunction: (name) => `get${(0, import_nodes.pascalCase)(name)}Instruction`,
instructionSyncInputType: (name) => `${(0, import_nodes.pascalCase)(name)}Input`,
instructionType: (name) => `${(0, import_nodes.pascalCase)(name)}Instruction`,
isDiscriminatedUnionFunction: (name) => `is${(0, import_nodes.pascalCase)(name)}`,
pdaFindFunction: (name) => `find${(0, import_nodes.pascalCase)(name)}Pda`,
pdaSeedsType: (name) => `${(0, import_nodes.pascalCase)(name)}Seeds`,
programAccountsEnum: (name) => `${(0, import_nodes.pascalCase)(name)}Account`,
programAccountsEnumVariant: (name) => `${(0, import_nodes.pascalCase)(name)}`,
programAccountsIdentifierFunction: (name) => `identify${(0, import_nodes.pascalCase)(name)}Account`,
programAddressConstant: (name) => `${(0, import_nodes.snakeCase)(name).toUpperCase()}_PROGRAM_ADDRESS`,
programErrorConstant: (name) => (0, import_nodes.snakeCase)(name).toUpperCase(),
programErrorConstantPrefix: (name) => `${(0, import_nodes.snakeCase)(name).toUpperCase()}_ERROR__`,
programErrorMessagesMap: (name) => `${(0, import_nodes.camelCase)(name)}ErrorMessages`,
programErrorUnion: (name) => `${(0, import_nodes.pascalCase)(name)}Error`,
programGetErrorMessageFunction: (name) => `get${(0, import_nodes.pascalCase)(name)}ErrorMessage`,
programInstructionsEnum: (name) => `${(0, import_nodes.pascalCase)(name)}Instruction`,
programInstructionsEnumVariant: (name) => `${(0, import_nodes.pascalCase)(name)}`,
programInstructionsIdentifierFunction: (name) => `identify${(0, import_nodes.pascalCase)(name)}Instruction`,
programInstructionsParsedUnionType: (name) => `Parsed${(0, import_nodes.pascalCase)(name)}Instruction`,
programIsErrorFunction: (name) => `is${(0, import_nodes.pascalCase)(name)}Error`,
resolverFunction: (name) => `${(0, import_nodes.camelCase)(name)}`
};
// src/utils/fragment.ts
var import_renderers_core = require("@codama/renderers-core");
function createFragment(content) {
return Object.freeze({ content, features: /* @__PURE__ */ new Set(), imports: createImportMap() });
}
function isFragment(value) {
return typeof value === "object" && value !== null && "content" in value;
}
function fragment(template, ...items) {
return (0, import_renderers_core.createFragmentTemplate)(template, items, isFragment, mergeFragments);
}
function mergeFragments(fragments, mergeContent) {
const filteredFragments = fragments.filter((f) => f !== void 0);
return Object.freeze({
content: mergeContent(filteredFragments.map((fragment2) => fragment2.content)),
features: new Set(filteredFragments.flatMap((f) => [...f.features])),
imports: mergeImportMaps(filteredFragments.map((f) => f.imports))
});
}
function use(importInput, module2) {
const importInfo = parseImportInput(importInput);
return addFragmentImports(createFragment(importInfo.usedIdentifier), module2, [importInput]);
}
function mergeFragmentImports(fragment2, importMaps) {
return Object.freeze({ ...fragment2, imports: mergeImportMaps([fragment2.imports, ...importMaps]) });
}
function addFragmentImports(fragment2, module2, importInputs) {
return Object.freeze({ ...fragment2, imports: addToImportMap(fragment2.imports, module2, importInputs) });
}
function removeFragmentImports(fragment2, module2, usedIdentifiers) {
return Object.freeze({ ...fragment2, imports: removeFromImportMap(fragment2.imports, module2, usedIdentifiers) });
}
function addFragmentFeatures(fragment2, features) {
return Object.freeze({ ...fragment2, features: /* @__PURE__ */ new Set([...fragment2.features, ...features]) });
}
function getExportAllFragment(module2) {
return fragment`export * from '${module2}';`;
}
function getDocblockFragment(lines, withLineJump = false) {
const lineJump = withLineJump ? "\n" : "";
if (lines.length === 0) return;
if (lines.length === 1) return fragment`/** ${lines[0]} */${lineJump}`;
const prefixedLines = lines.map((line) => line ? ` * ${line}` : " *");
return fragment`/**\n${prefixedLines.join("\n")}\n */${lineJump}`;
}
function getPageFragment(page, scope) {
const header = getDocblockFragment([
"This code was AUTOGENERATED using the Codama library.",
"Please DO NOT EDIT THIS FILE, instead use visitors",
"to add features, then rerun Codama to update it.",
"",
"@see https://github.com/codama-idl/codama"
]);
const imports = page.imports.size === 0 ? void 0 : fragment`${importMapToString(page.imports, scope.dependencyMap, scope.useGranularImports)}`;
return mergeFragments([header, imports, page], (cs) => cs.join("\n\n"));
}
// src/utils/typeManifest.ts
function typeManifest(input = {}) {
return Object.freeze({
decoder: fragment``,
encoder: fragment``,
isEnum: false,
looseType: fragment``,
strictType: fragment``,
value: fragment``,
...input
});
}
function mergeTypeManifests(manifests, options = {}) {
const { mergeTypes, mergeCodecs, mergeValues } = options;
const merge = (fragmentFn, mergeFn) => mergeFn ? mergeFragments(manifests.map(fragmentFn), mergeFn) : fragment``;
return Object.freeze({
decoder: merge((m) => m.decoder, mergeCodecs),
encoder: merge((m) => m.encoder, mergeCodecs),
isEnum: false,
looseType: merge((m) => m.looseType, mergeTypes),
strictType: merge((m) => m.strictType, mergeTypes),
value: merge((m) => m.value, mergeValues)
});
}
// src/visitors/getRenderMapVisitor.ts
var import_nodes28 = require("@codama/nodes");
var import_renderers_core13 = require("@codama/renderers-core");
var import_visitors_core29 = require("@codama/visitors-core");
// src/fragments/accountFetchHelpers.ts
var import_visitors_core2 = require("@codama/visitors-core");
// src/utils/async.ts
var import_nodes2 = require("@codama/nodes");
var import_visitors_core = require("@codama/visitors-core");
function hasAsyncFunction(instructionNode, resolvedInputs, asyncResolvers) {
const hasByteDeltasAsync = (instructionNode.byteDeltas ?? []).some(
({ value }) => (0, import_nodes2.isNode)(value, "resolverValueNode") && asyncResolvers.includes(value.name)
);
const hasRemainingAccountsAsync = (instructionNode.remainingAccounts ?? []).some(
({ value }) => (0, import_nodes2.isNode)(value, "resolverValueNode") && asyncResolvers.includes(value.name)
);
return hasAsyncDefaultValues(resolvedInputs, asyncResolvers) || hasByteDeltasAsync || hasRemainingAccountsAsync;
}
function hasAsyncDefaultValues(resolvedInputs, asyncResolvers) {
return resolvedInputs.some(
(input) => !!input.defaultValue && isAsyncDefaultValue(input.defaultValue, asyncResolvers)
);
}
function isAsyncDefaultValue(defaultValue, asyncResolvers) {
switch (defaultValue.kind) {
case "pdaValueNode":
return true;
case "resolverValueNode":
return asyncResolvers.includes(defaultValue.name);
case "conditionalValueNode":
return isAsyncDefaultValue(defaultValue.condition, asyncResolvers) || (defaultValue.ifFalse == null ? false : isAsyncDefaultValue(defaultValue.ifFalse, asyncResolvers)) || (defaultValue.ifTrue == null ? false : isAsyncDefaultValue(defaultValue.ifTrue, asyncResolvers));
default:
return false;
}
}
function getInstructionDependencies(input, asyncResolvers, useAsync) {
if ((0, import_nodes2.isNode)(input, "instructionNode")) {
return (0, import_visitors_core.deduplicateInstructionDependencies)([
...input.accounts.flatMap((x) => getInstructionDependencies(x, asyncResolvers, useAsync)),
...input.arguments.flatMap((x) => getInstructionDependencies(x, asyncResolvers, useAsync)),
...(input.extraArguments ?? []).flatMap((x) => getInstructionDependencies(x, asyncResolvers, useAsync))
]);
}
if (!input.defaultValue) return [];
const getNestedDependencies = (defaultValue) => {
if (!defaultValue) return [];
return getInstructionDependencies({ ...input, defaultValue }, asyncResolvers, useAsync);
};
if ((0, import_nodes2.isNode)(input.defaultValue, ["accountValueNode", "accountBumpValueNode"])) {
return [(0, import_nodes2.accountValueNode)(input.defaultValue.name)];
}
if ((0, import_nodes2.isNode)(input.defaultValue, ["argumentValueNode"])) {
return [(0, import_nodes2.argumentValueNode)(input.defaultValue.name)];
}
if ((0, import_nodes2.isNode)(input.defaultValue, "pdaValueNode")) {
const dependencies = /* @__PURE__ */ new Map();
input.defaultValue.seeds.forEach((seed) => {
if ((0, import_nodes2.isNode)(seed.value, ["accountValueNode", "argumentValueNode"])) {
dependencies.set(seed.value.name, { ...seed.value });
}
});
return [...dependencies.values()];
}
if ((0, import_nodes2.isNode)(input.defaultValue, "resolverValueNode")) {
const isSynchronousResolver = !asyncResolvers.includes(input.defaultValue.name);
if (useAsync || isSynchronousResolver) {
return input.defaultValue.dependsOn ?? [];
}
}
if ((0, import_nodes2.isNode)(input.defaultValue, "conditionalValueNode")) {
return (0, import_visitors_core.deduplicateInstructionDependencies)([
...getNestedDependencies(input.defaultValue.condition),
...getNestedDependencies(input.defaultValue.ifTrue),
...getNestedDependencies(input.defaultValue.ifFalse)
]);
}
return [];
}
// src/utils/codecs.ts
var import_codecs_strings = require("@solana/codecs-strings");
function getBytesFromBytesValueNode(node) {
switch (node.encoding) {
case "utf8":
return (0, import_codecs_strings.getUtf8Encoder)().encode(node.data);
case "base16":
return (0, import_codecs_strings.getBase16Encoder)().encode(node.data);
case "base58":
return (0, import_codecs_strings.getBase58Encoder)().encode(node.data);
case "base64":
default:
return (0, import_codecs_strings.getBase64Encoder)().encode(node.data);
}
}
// src/utils/customData.ts
var import_nodes3 = require("@codama/nodes");
var parseCustomDataOptions = (customDataOptions, defaultSuffix) => new Map(
customDataOptions.map((o) => {
const options = typeof o === "string" ? { name: o } : o;
const importAs = (0, import_nodes3.camelCase)(options.importAs ?? `${options.name}${defaultSuffix}`);
const importFrom = options.importFrom ?? "hooked";
return [
(0, import_nodes3.camelCase)(options.name),
{
extract: options.extract ?? false,
extractAs: options.extractAs ? (0, import_nodes3.camelCase)(options.extractAs) : importAs,
importAs,
importFrom,
linkNode: (0, import_nodes3.definedTypeLinkNode)(importAs)
}
];
})
);
var getDefinedTypeNodesToExtract = (nodes, parsedCustomDataOptions) => nodes.flatMap((node) => {
const options = parsedCustomDataOptions.get(node.name);
if (!options || !options.extract) return [];
if ((0, import_nodes3.isNode)(node, "accountNode")) {
return [(0, import_nodes3.definedTypeNode)({ name: options.extractAs, type: { ...node.data } })];
}
return [
(0, import_nodes3.definedTypeNode)({
name: options.extractAs,
type: (0, import_nodes3.structTypeNodeFromInstructionArgumentNodes)(node.arguments)
})
];
});
// src/utils/linkOverrides.ts
var import_errors = require("@codama/errors");
function getImportFromFactory(overrides, customAccountData, customInstructionData) {
const customDataOverrides = Object.fromEntries(
[...customAccountData.values(), ...customInstructionData.values()].map(({ importFrom, importAs }) => [
importAs,
importFrom
])
);
const linkOverrides = {
accounts: overrides.accounts ?? {},
definedTypes: { ...customDataOverrides, ...overrides.definedTypes },
instructions: overrides.instructions ?? {},
pdas: overrides.pdas ?? {},
programs: overrides.programs ?? {},
resolvers: overrides.resolvers ?? {}
};
return (node) => {
const kind = node.kind;
switch (kind) {
case "accountLinkNode":
return linkOverrides.accounts[node.name] ?? "generatedAccounts";
case "definedTypeLinkNode":
return linkOverrides.definedTypes[node.name] ?? "generatedTypes";
case "instructionLinkNode":
return linkOverrides.instructions[node.name] ?? "generatedInstructions";
case "pdaLinkNode":
return linkOverrides.pdas[node.name] ?? "generatedPdas";
case "programLinkNode":
return linkOverrides.programs[node.name] ?? "generatedPrograms";
case "resolverValueNode":
return linkOverrides.resolvers[node.name] ?? "hooked";
default:
throw new import_errors.CodamaError(import_errors.CODAMA_ERROR__UNEXPECTED_NODE_KIND, {
expectedKinds: [
"AccountLinkNode",
"DefinedTypeLinkNode",
"InstructionLinkNode",
"PdaLinkNode",
"ProgramLinkNode",
"resolverValueNode"
],
kind,
node
});
}
};
}
// src/fragments/accountFetchHelpers.ts
function getAccountFetchHelpersFragment(scope) {
const { accountPath, typeManifest: typeManifest2, nameApi, customAccountData } = scope;
const accountNode = (0, import_visitors_core2.getLastNodeFromPath)(accountPath);
const decodeFunction = nameApi.accountDecodeFunction(accountNode.name);
const fetchAllFunction = nameApi.accountFetchAllFunction(accountNode.name);
const fetchAllMaybeFunction = nameApi.accountFetchAllMaybeFunction(accountNode.name);
const fetchFunction = nameApi.accountFetchFunction(accountNode.name);
const fetchMaybeFunction = nameApi.accountFetchMaybeFunction(accountNode.name);
const hasCustomData = customAccountData.has(accountNode.name);
const accountType = hasCustomData ? typeManifest2.strictType : nameApi.dataType(accountNode.name);
const decoderFunction = hasCustomData ? typeManifest2.decoder : `${nameApi.decoderFunction(accountNode.name)}()`;
return (0, import_visitors_core2.pipe)(
fragment`export function ${decodeFunction}<TAddress extends string = string>(encodedAccount: EncodedAccount<TAddress>): Account<${accountType}, TAddress>;
export function ${decodeFunction}<TAddress extends string = string>(encodedAccount: MaybeEncodedAccount<TAddress>): MaybeAccount<${accountType}, TAddress>;
export function ${decodeFunction}<TAddress extends string = string>(encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>): Account<${accountType}, TAddress> | MaybeAccount<${accountType}, TAddress> {
return decodeAccount(encodedAccount as MaybeEncodedAccount<TAddress>, ${decoderFunction});
}
export async function ${fetchFunction}<TAddress extends string = string>(
rpc: Parameters<typeof fetchEncodedAccount>[0],
address: Address<TAddress>,
config?: FetchAccountConfig,
): Promise<Account<${accountType}, TAddress>> {
const maybeAccount = await ${fetchMaybeFunction}(rpc, address, config);
assertAccountExists(maybeAccount);
return maybeAccount;
}
export async function ${fetchMaybeFunction}<TAddress extends string = string>(
rpc: Parameters<typeof fetchEncodedAccount>[0],
address: Address<TAddress>,
config?: FetchAccountConfig,
): Promise<MaybeAccount<${accountType}, TAddress>> {
const maybeAccount = await fetchEncodedAccount(rpc, address, config);
return ${decodeFunction}(maybeAccount);
}
export async function ${fetchAllFunction}(
rpc: Parameters<typeof fetchEncodedAccounts>[0],
addresses: Array<Address>,
config?: FetchAccountsConfig,
): Promise<Account<${accountType}>[]> {
const maybeAccounts = await ${fetchAllMaybeFunction}(rpc, addresses, config);
assertAccountsExist(maybeAccounts);
return maybeAccounts;
}
export async function ${fetchAllMaybeFunction}(
rpc: Parameters<typeof fetchEncodedAccounts>[0],
addresses: Array<Address>,
config?: FetchAccountsConfig,
): Promise<MaybeAccount<${accountType}>[]> {
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
return maybeAccounts.map((maybeAccount) => ${decodeFunction}(maybeAccount));
}`,
(f) => addFragmentImports(f, "solanaAddresses", ["type Address"]),
(f) => addFragmentImports(f, "solanaAccounts", [
"type Account",
"assertAccountExists",
"assertAccountsExist",
"decodeAccount",
"type EncodedAccount",
"fetchEncodedAccount",
"fetchEncodedAccounts",
"type FetchAccountConfig",
"type FetchAccountsConfig",
"type MaybeAccount",
"type MaybeEncodedAccount"
])
);
}
// src/fragments/accountPage.ts
var import_nodes9 = require("@codama/nodes");
var import_visitors_core7 = require("@codama/visitors-core");
// src/fragments/accountPdaHelpers.ts
var import_nodes4 = require("@codama/nodes");
var import_visitors_core3 = require("@codama/visitors-core");
function getAccountPdaHelpersFragment(scope) {
const { accountPath, nameApi, linkables, customAccountData, typeManifest: typeManifest2 } = scope;
const accountNode = (0, import_visitors_core3.getLastNodeFromPath)(accountPath);
const pdaNode = accountNode.pda ? linkables.get([...accountPath, accountNode.pda]) : void 0;
if (!pdaNode) return;
const accountType = customAccountData.has(accountNode.name) ? typeManifest2.strictType : nameApi.dataType(accountNode.name);
const importFrom = "generatedPdas";
const pdaSeedsType = nameApi.pdaSeedsType(pdaNode.name);
const findPdaFunction = nameApi.pdaFindFunction(pdaNode.name);
const hasVariableSeeds = pdaNode.seeds.filter((0, import_nodes4.isNodeFilter)("variablePdaSeedNode")).length > 0;
const fetchFromSeedsFunction = nameApi.accountFetchFromSeedsFunction(accountNode.name);
const fetchMaybeFromSeedsFunction = nameApi.accountFetchMaybeFromSeedsFunction(accountNode.name);
const fetchMaybeFunction = nameApi.accountFetchMaybeFunction(accountNode.name);
return (0, import_visitors_core3.pipe)(
fragment`export async function ${fetchFromSeedsFunction}(
rpc: Parameters<typeof fetchEncodedAccount>[0],
${hasVariableSeeds ? `seeds: ${pdaSeedsType},` : ""}
config: FetchAccountConfig & { programAddress?: Address } = {},
): Promise<Account<${accountType}>> {
const maybeAccount = await ${fetchMaybeFromSeedsFunction}(rpc, ${hasVariableSeeds ? "seeds, " : ""}config);
assertAccountExists(maybeAccount);
return maybeAccount;
}
export async function ${fetchMaybeFromSeedsFunction}(
rpc: Parameters<typeof fetchEncodedAccount>[0],
${hasVariableSeeds ? `seeds: ${pdaSeedsType},` : ""}
config: FetchAccountConfig & { programAddress?: Address } = {},
): Promise<MaybeAccount<${accountType}>> {
const { programAddress, ...fetchConfig } = config;
const [address] = await ${findPdaFunction}(${hasVariableSeeds ? "seeds, " : ""}{ programAddress });
return await ${fetchMaybeFunction}(rpc, address, fetchConfig);
}`,
(f) => addFragmentImports(f, importFrom, hasVariableSeeds ? [pdaSeedsType, findPdaFunction] : [findPdaFunction]),
(f) => addFragmentImports(f, "solanaAddresses", ["type Address"]),
(f) => addFragmentImports(f, "solanaAccounts", [
"type Account",
"assertAccountExists",
"type FetchAccountConfig",
"type MaybeAccount"
])
);
}
// src/fragments/accountSizeHelpers.ts
var import_visitors_core4 = require("@codama/visitors-core");
function getAccountSizeHelpersFragment(scope) {
const { accountPath, nameApi } = scope;
const accountNode = (0, import_visitors_core4.getLastNodeFromPath)(accountPath);
if (accountNode.size == null) return;
const getSizeFunction = nameApi.accountGetSizeFunction(accountNode.name);
return fragment`export function ${getSizeFunction}(): number {
return ${accountNode.size};
}`;
}
// src/fragments/accountType.ts
var import_nodes7 = require("@codama/nodes");
var import_visitors_core5 = require("@codama/visitors-core");
// src/fragments/type.ts
function getTypeFragment(scope) {
const { name, manifest, nameApi, docs = [] } = scope;
const docblock = getDocblockFragment(docs, true);
const strictName = nameApi.dataType(name);
const looseName = nameApi.dataArgsType(name);
const aliasedLooseName = `export type ${looseName} = ${strictName};`;
if (manifest.isEnum) {
return fragment`${docblock}export enum ${strictName} ${manifest.strictType};\n\n${aliasedLooseName}`;
}
const looseExport = manifest.strictType.content === manifest.looseType.content ? aliasedLooseName : fragment`export type ${looseName} = ${manifest.looseType};`;
return fragment`${docblock}export type ${strictName} = ${manifest.strictType};\n\n${looseExport}`;
}
// src/fragments/typeDecoder.ts
var import_nodes5 = require("@codama/nodes");
function getTypeDecoderFragment(scope) {
const { name, node, manifest, nameApi, docs = [] } = scope;
const decoderFunction = nameApi.decoderFunction(name);
const strictName = nameApi.dataType(name);
const docblock = getDocblockFragment(docs, true);
const decoderType = use(
typeof scope.size === "number" ? "type FixedSizeDecoder" : "type Decoder",
"solanaCodecsCore"
);
const useTypeCast = (0, import_nodes5.isNode)(node, "enumTypeNode") && (0, import_nodes5.isDataEnum)(node) && typeof scope.size === "number";
const typeCast = useTypeCast ? fragment` as ${decoderType}<${strictName}>` : "";
return fragment`${docblock}export function ${decoderFunction}(): ${decoderType}<${strictName}> {
return ${manifest.decoder}${typeCast};
}`;
}
// src/fragments/typeEncoder.ts
var import_nodes6 = require("@codama/nodes");
function getTypeEncoderFragment(scope) {
const { name, node, manifest, nameApi, docs = [] } = scope;
const encoderFunction = nameApi.encoderFunction(name);
const looseName = nameApi.dataArgsType(name);
const docblock = getDocblockFragment(docs, true);
const encoderType = use(
typeof scope.size === "number" ? "type FixedSizeEncoder" : "type Encoder",
"solanaCodecsCore"
);
const useTypeCast = (0, import_nodes6.isNode)(node, "enumTypeNode") && (0, import_nodes6.isDataEnum)(node) && typeof scope.size === "number";
const typeCast = useTypeCast ? fragment` as ${encoderType}<${looseName}>` : "";
return fragment`${docblock}export function ${encoderFunction}(): ${encoderType}<${looseName}> {
return ${manifest.encoder}${typeCast};
}`;
}
// src/fragments/typeCodec.ts
function getTypeCodecFragment(scope) {
const { codecDocs = [], name, nameApi } = scope;
const codecFunction = nameApi.codecFunction(name);
const decoderFunction = nameApi.decoderFunction(name);
const encoderFunction = nameApi.encoderFunction(name);
const looseName = nameApi.dataArgsType(name);
const strictName = nameApi.dataType(name);
const docblock = getDocblockFragment(codecDocs, true);
const codecType = use(typeof scope.size === "number" ? "type FixedSizeCodec" : "type Codec", "solanaCodecsCore");
return mergeFragments(
[
getTypeEncoderFragment({ ...scope, docs: scope.encoderDocs }),
getTypeDecoderFragment({ ...scope, docs: scope.decoderDocs }),
fragment`${docblock}export function ${codecFunction}(): ${codecType}<${looseName}, ${strictName}> {
return ${use("combineCodec", "solanaCodecsCore")}(${encoderFunction}(), ${decoderFunction}());
}`
],
(renders) => renders.join("\n\n")
);
}
// src/fragments/typeWithCodec.ts
function getTypeWithCodecFragment(scope) {
return mergeFragments(
[getTypeFragment({ ...scope, docs: scope.typeDocs }), getTypeCodecFragment(scope)],
(renders) => renders.join("\n\n")
);
}
// src/fragments/accountType.ts
function getAccountTypeFragment(scope) {
const { accountPath, typeManifest: typeManifest2, nameApi, customAccountData } = scope;
const accountNode = (0, import_visitors_core5.getLastNodeFromPath)(accountPath);
if (customAccountData.has(accountNode.name)) return;
return getTypeWithCodecFragment({
manifest: typeManifest2,
name: accountNode.name,
nameApi,
node: (0, import_nodes7.resolveNestedTypeNode)(accountNode.data),
size: scope.size
});
}
// src/fragments/discriminatorConstants.ts
var import_nodes8 = require("@codama/nodes");
var import_visitors_core6 = require("@codama/visitors-core");
function getDiscriminatorConstantsFragment(scope) {
const fragments = scope.discriminatorNodes.map((node) => getDiscriminatorConstantFragment(node, scope)).filter(Boolean);
return mergeFragments(fragments, (c) => c.join("\n\n"));
}
function getDiscriminatorConstantFragment(discriminatorNode, scope) {
switch (discriminatorNode.kind) {
case "constantDiscriminatorNode":
return getConstantDiscriminatorConstantFragment(discriminatorNode, scope);
case "fieldDiscriminatorNode":
return getFieldDiscriminatorConstantFragment(discriminatorNode, scope);
default:
return null;
}
}
function getConstantDiscriminatorConstantFragment(discriminatorNode, scope) {
const { discriminatorNodes, typeManifestVisitor, prefix } = scope;
const index = discriminatorNodes.filter((0, import_nodes8.isNodeFilter)("constantDiscriminatorNode")).indexOf(discriminatorNode);
const suffix = index <= 0 ? "" : `_${index + 1}`;
const name = (0, import_nodes8.camelCase)(`${prefix}_discriminator${suffix}`);
const encoder = (0, import_visitors_core6.visit)(discriminatorNode.constant.type, typeManifestVisitor).encoder;
const value = (0, import_visitors_core6.visit)(discriminatorNode.constant.value, typeManifestVisitor).value;
return getConstantFragment({ ...scope, encoder, name, value });
}
function getFieldDiscriminatorConstantFragment(discriminatorNode, scope) {
const { fields, prefix, typeManifestVisitor } = scope;
const field = fields.find((f) => f.name === discriminatorNode.name);
if (!field || !field.defaultValue || !(0, import_nodes8.isNode)(field.defaultValue, import_nodes8.VALUE_NODES)) {
return null;
}
const name = (0, import_nodes8.camelCase)(`${prefix}_${discriminatorNode.name}`);
const encoder = (0, import_visitors_core6.visit)(field.type, typeManifestVisitor).encoder;
const value = (0, import_visitors_core6.visit)(field.defaultValue, typeManifestVisitor).value;
return getConstantFragment({ ...scope, encoder, name, value });
}
function getConstantFragment(scope) {
const { encoder, name, nameApi, value } = scope;
const constantName = nameApi.constant(name);
const constantFunction = nameApi.constantFunction(name);
return fragment`export const ${constantName} = ${value};\n\nexport function ${constantFunction}() { return ${encoder}.encode(${constantName}); }`;
}
// src/fragments/accountPage.ts
function getAccountPageFragment(scope) {
const node = (0, import_visitors_core7.getLastNodeFromPath)(scope.accountPath);
if (!(0, import_visitors_core7.findProgramNodeFromPath)(scope.accountPath)) {
throw new Error("Account must be visited inside a program.");
}
const typeManifest2 = (0, import_visitors_core7.visit)(node, scope.typeManifestVisitor);
const fields = (0, import_nodes9.resolveNestedTypeNode)(node.data).fields;
return mergeFragments(
[
getDiscriminatorConstantsFragment({
...scope,
discriminatorNodes: node.discriminators ?? [],
fields,
prefix: node.name
}),
getAccountTypeFragment({ ...scope, typeManifest: typeManifest2 }),
getAccountFetchHelpersFragment({ ...scope, typeManifest: typeManifest2 }),
getAccountSizeHelpersFragment(scope),
getAccountPdaHelpersFragment({ ...scope, typeManifest: typeManifest2 })
],
(cs) => cs.join("\n\n")
);
}
// src/fragments/discriminatorCondition.ts
var import_nodes10 = require("@codama/nodes");
var import_renderers_core2 = require("@codama/renderers-core");
var import_visitors_core8 = require("@codama/visitors-core");
var import_codecs_strings2 = require("@solana/codecs-strings");
function getDiscriminatorConditionFragment(scope) {
return (0, import_visitors_core8.pipe)(
mergeFragments(
scope.discriminators.flatMap((discriminator) => {
if ((0, import_nodes10.isNode)(discriminator, "sizeDiscriminatorNode")) {
return [getSizeConditionFragment(discriminator, scope)];
}
if ((0, import_nodes10.isNode)(discriminator, "constantDiscriminatorNode")) {
return [getByteConditionFragment(discriminator, scope)];
}
if ((0, import_nodes10.isNode)(discriminator, "fieldDiscriminatorNode")) {
return [getFieldConditionFragment(discriminator, scope)];
}
return [];
}),
(c) => c.join(" && ")
),
(f) => (0, import_renderers_core2.mapFragmentContent)(f, (c) => `if (${c}) { ${scope.ifTrue} }`)
);
}
function getSizeConditionFragment(discriminator, scope) {
const { dataName } = scope;
return fragment`${dataName}.length === ${discriminator.size}`;
}
function getByteConditionFragment(discriminator, scope) {
const { dataName, typeManifestVisitor } = scope;
const constant = (0, import_visitors_core8.visit)(discriminator.constant, typeManifestVisitor).value;
return fragment`${use("containsBytes", "solanaCodecsCore")}(${dataName}, ${constant}, ${discriminator.offset})`;
}
function getFieldConditionFragment(discriminator, scope) {
const field = scope.struct.fields.find((f) => f.name === discriminator.name);
if (!field || !field.defaultValue) {
throw new Error(
`Field discriminator "${discriminator.name}" does not have a matching argument with default value.`
);
}
if ((0, import_nodes10.isNode)(field.type, "arrayTypeNode") && (0, import_nodes10.isNode)(field.type.item, "numberTypeNode") && field.type.item.format === "u8" && (0, import_nodes10.isNode)(field.type.count, "fixedCountNode") && (0, import_nodes10.isNode)(field.defaultValue, "arrayValueNode") && field.defaultValue.items.every((0, import_nodes10.isNodeFilter)("numberValueNode"))) {
const base64Bytes = (0, import_codecs_strings2.getBase64Decoder)().decode(
new Uint8Array(field.defaultValue.items.map((node) => node.number))
);
return getByteConditionFragment(
(0, import_nodes10.constantDiscriminatorNode)((0, import_nodes10.constantValueNodeFromBytes)("base64", base64Bytes), discriminator.offset),
scope
);
}
return getByteConditionFragment(
(0, import_nodes10.constantDiscriminatorNode)((0, import_nodes10.constantValueNode)(field.type, field.defaultValue), discriminator.offset),
scope
);
}
// src/fragments/errorPage.ts
function getErrorPageFragment(scope) {
return mergeFragments(
[
getConstantsFragment(scope),
getConstantUnionTypeFragment(scope),
getErrorMessagesFragment(scope),
getErrorMessageFunctionFragment(scope),
getIsErrorFunctionFragment(scope)
],
(cs) => cs.join("\n\n")
);
}
function getConstantsFragment(scope) {
const constantPrefix = scope.nameApi.programErrorConstantPrefix(scope.programNode.name);
return mergeFragments(
[...scope.programNode.errors].sort((a, b) => a.code - b.code).map((error) => {
const docs = getDocblockFragment(error.docs ?? [], true);
const name = constantPrefix + scope.nameApi.programErrorConstant(error.name);
return fragment`${docs}export const ${name} = 0x${error.code.toString(16)}; // ${error.code}`;
}),
(cs) => cs.join("\n")
);
}
function getConstantUnionTypeFragment(scope) {
const constantPrefix = scope.nameApi.programErrorConstantPrefix(scope.programNode.name);
const typeName = scope.nameApi.programErrorUnion(scope.programNode.name);
const errorTypes = mergeFragments(
[...scope.programNode.errors].sort((a, b) => a.name.localeCompare(b.name)).map((error) => fragment`typeof ${constantPrefix + scope.nameApi.programErrorConstant(error.name)}`),
(cs) => cs.join(" | ")
);
return fragment`export type ${typeName} = ${errorTypes};`;
}
function getErrorMessagesFragment(scope) {
const mapName = scope.nameApi.programErrorMessagesMap(scope.programNode.name);
const errorUnionType = scope.nameApi.programErrorUnion(scope.programNode.name);
const constantPrefix = scope.nameApi.programErrorConstantPrefix(scope.programNode.name);
const messageEntries = mergeFragments(
[...scope.programNode.errors].sort((a, b) => a.name.localeCompare(b.name)).map((error) => {
const constantName = constantPrefix + scope.nameApi.programErrorConstant(error.name);
const escapedMessage = error.message.replace(/`/g, "\\`");
return fragment`[${constantName}]: \`${escapedMessage}\``;
}),
(cs) => cs.join(", ")
);
return fragment`let ${mapName}: Record<${errorUnionType}, string> | undefined;
if (process.env.NODE_ENV !== 'production') {
${mapName} = { ${messageEntries} };
}`;
}
function getErrorMessageFunctionFragment(scope) {
const functionName = scope.nameApi.programGetErrorMessageFunction(scope.programNode.name);
const errorUnionType = scope.nameApi.programErrorUnion(scope.programNode.name);
const messageMapName = scope.nameApi.programErrorMessagesMap(scope.programNode.name);
return fragment`export function ${functionName}(code: ${errorUnionType}): string {
if (process.env.NODE_ENV !== 'production') {
return (${messageMapName} as Record<${errorUnionType}, string>)[code];
}
return 'Error message not available in production bundles.';
}`;
}
function getIsErrorFunctionFragment(scope) {
const { programNode, nameApi } = scope;
const programAddressConstant = use(nameApi.programAddressConstant(programNode.name), "generatedPrograms");
const functionName = nameApi.programIsErrorFunction(programNode.name);
const programErrorUnion = nameApi.programErrorUnion(programNode.name);
return fragment`export function ${functionName}<TProgramErrorCode extends ${programErrorUnion}>(
error: unknown,
transactionMessage: { instructions: Record<number, { programAddress: ${use("type Address", "solanaAddresses")} }> },
code?: TProgramErrorCode,
): error is ${use("type SolanaError", "solanaErrors")}<typeof ${use("type SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM", "solanaErrors")}> & Readonly<{ context: Readonly<{ code: TProgramErrorCode }> }> {
return ${use("isProgramError", "solanaPrograms")}<TProgramErrorCode>(error, transactionMessage, ${programAddressConstant}, code);
}`;
}
// src/fragments/indexPage.ts
function getIndexPageFragment(items) {
if (items.length === 0) return;
const names = items.map((item) => item.name).sort((a, b) => a.localeCompare(b)).map((name) => getExportAllFragment(`./${name}`));
return mergeFragments(names, (cs) => cs.join("\n"));
}
// src/fragments/instructionAccountMeta.ts
var import_nodes11 = require("@codama/nodes");
function getInstructionAccountMetaFragment(instructionAccountNode) {
const typeParam = `TAccount${(0, import_nodes11.pascalCase)(instructionAccountNode.name)}`;
if (instructionAccountNode.isSigner === true && instructionAccountNode.isWritable) {
return fragment`${use("type WritableSignerAccount", "solanaInstructions")}<${typeParam}> & ${use("type AccountSignerMeta", "solanaSigners")}<${typeParam}>`;
}
if (instructionAccountNode.isSigner === true) {
return fragment`${use("type ReadonlySignerAccount", "solanaInstructions")}<${typeParam}> & ${use("type AccountSignerMeta", "solanaSigners")}<${typeParam}>`;
}
if (instructionAccountNode.isWritable) {
return fragment`${use("type WritableAccount", "solanaInstructions")}<${typeParam}>`;
}
return fragment`${use("type ReadonlyAccount", "solanaInstructions")}<${typeParam}>`;
}
// src/fragments/instructionAccountTypeParam.ts
var import_nodes12 = require("@codama/nodes");
var import_visitors_core9 = require("@codama/visitors-core");
function getInstructionAccountTypeParamFragment(scope) {
const { instructionAccountPath, allowAccountMeta, linkables } = scope;
const instructionAccountNode = (0, import_visitors_core9.getLastNodeFromPath)(instructionAccountPath);
const instructionNode = (0, import_visitors_core9.findInstructionNodeFromPath)(instructionAccountPath);
const programNode = (0, import_visitors_core9.findProgramNodeFromPath)(instructionAccountPath);
const typeParam = `TAccount${(0, import_nodes12.pascalCase)(instructionAccountNode.name)}`;
const accountMeta = allowAccountMeta ? fragment` | ${use("type AccountMeta", "solanaInstructions")}<string>` : void 0;
if (instructionNode.optionalAccountStrategy === "omitted" && instructionAccountNode.isOptional) {
return fragment`${typeParam} extends string${accountMeta} | undefined = undefined`;
}
const defaultAddress = getDefaultAddress(instructionAccountNode.defaultValue, programNode.publicKey, linkables);
return fragment`${typeParam} extends string${accountMeta} = ${defaultAddress}`;
}
function getDefaultAddress(defaultValue, programId, linkables) {
switch (defaultValue?.kind) {
case "publicKeyValueNode":
return `"${defaultValue.publicKey}"`;
case "programLinkNode":
const programNode = linkables.get([defaultValue]);
return programNode ? `"${programNode.publicKey}"` : "string";
case "programIdValueNode":
return `"${programId}"`;
default:
return "string";
}
}
// src/fragments/instructionByteDelta.ts
var import_nodes13 = require("@codama/nodes");
var import_renderers_core3 = require("@codama/renderers-core");
var import_visitors_core10 = require("@codama/visitors-core");
function getInstructionByteDeltaFragment(scope) {
const { byteDeltas } = (0, import_visitors_core10.getLastNodeFromPath)(scope.instructionPath);
const fragments = (byteDeltas ?? []).flatMap((c) => getByteDeltaFragment(c, scope));
if (fragments.length === 0) return;
return mergeFragments(
fragments,
(c) => `// Bytes created or reallocated by the instruction.
const byteDelta: number = [${c.join(",")}].reduce((a, b) => a + b, 0);`
);
}
function getByteDeltaFragment(byteDelta, scope) {
let bytesFragment = (() => {
if ((0, import_nodes13.isNode)(byteDelta.value, "numberValueNode")) {
return getNumberValueNodeFragment(byteDelta);
}
if ((0, import_nodes13.isNode)(byteDelta.value, "argumentValueNode")) {
return getArgumentValueNodeFragment(byteDelta);
}
if ((0, import_nodes13.isNode)(byteDelta.value, "accountLinkNode")) {
return getAccountLinkNodeFragment(byteDelta, scope);
}
if ((0, import_nodes13.isNode)(byteDelta.value, "resolverValueNode")) {
return getResolverValueNodeFragment(byteDelta, scope);
}
return null;
})();
if (bytesFragment === null) return [];
if (byteDelta.withHeader) {
bytesFragment = fragment`${bytesFragment} + ${use("BASE_ACCOUNT_SIZE", "solanaAccounts")}`;
}
if (byteDelta.subtract) {
bytesFragment = (0, import_visitors_core10.pipe)(bytesFragment, (f) => (0, import_renderers_core3.mapFragmentContent)(f, (c) => `- (${c})`));
}
return [bytesFragment];
}
function getNumberValueNodeFragment(byteDelta) {
(0, import_nodes13.assertIsNode)(byteDelta.value, "numberValueNode");
return fragment`${byteDelta.value.number}`;
}
function getArgumentValueNodeFragment(byteDelta) {
(0, import_nodes13.assertIsNode)(byteDelta.value, "argumentValueNode");
const argumentName = (0, import_nodes13.camelCase)(byteDelta.value.name);
return fragment`Number(args.${argumentName})`;
}
function getAccountLinkNodeFragment(byteDelta, scope) {
(0, import_nodes13.assertIsNode)(byteDelta.value, "accountLinkNode");
const functionName = use(
scope.nameApi.accountGetSizeFunction(byteDelta.value.name),
scope.getImportFrom(byteDelta.value)
);
return fragment`${functionName}()`;
}
function getResolverValueNodeFragment(byteDelta, scope) {
(0, import_nodes13.assertIsNode)(byteDelta.value, "resolverValueNode");
const isAsync = scope.asyncResolvers.includes(byteDelta.value.name);
if (!scope.useAsync && isAsync) return null;
const awaitKeyword = scope.useAsync && isAsync ? "await " : "";
const functionName = use(
scope.nameApi.resolverFunction(byteDelta.value.name),
scope.getImportFrom(byteDelta.value)
);
return (0, import_visitors_core10.pipe)(
fragment`${awaitKeyword}${functionName}(resolverScope)`,
(f) => addFragmentFeatures(f, ["instruction:resolverScopeVariable"])
);
}
// src/fragments/instructionData.ts
var import_nodes14 = require("@codama/nodes");
var import_visitors_core11 = require("@codama/visitors-core");
function getInstructionDataFragment(scope) {
const { instructionPath, dataArgsManifest, nameApi, customInstructionData } = scope;
const instructionNode = (0, import_visitors_core11.getLastNodeFromPath)(instructionPath);
if (instructionNode.arguments.length === 0 || customInstructionData.has(instructionNode.name)) return;
const instructionDataName = nameApi.instructionDataType(instructionNode.name);
return get