@codama/renderers-js
Version: 
JavaScript renderer compatible with the Solana Kit library
1,062 lines (1,025 loc) • 161 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