From a4052c4f3bd2bb1056cf192e10f0ead0ccd4d0ff Mon Sep 17 00:00:00 2001 From: Callum Date: Wed, 28 Feb 2024 17:05:44 +0000 Subject: [PATCH] fixup! Render a union type for parsed instructions in js-experimental --- .changeset/mighty-bats-relax.md | 5 ++++ src/renderers/js-experimental/ImportMap.ts | 1 + .../fragments/programInstructions.ts | 12 ++++------ .../js-experimental/nameTransformers.ts | 4 ++-- .../js-experimental/programsPage.test.ts | 24 +++++++++++++++++++ 5 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 .changeset/mighty-bats-relax.md diff --git a/.changeset/mighty-bats-relax.md b/.changeset/mighty-bats-relax.md new file mode 100644 index 000000000..5a782e795 --- /dev/null +++ b/.changeset/mighty-bats-relax.md @@ -0,0 +1,5 @@ +--- +'@metaplex-foundation/kinobi': patch +--- + +Render a union type for parsed instructions in js-experimental diff --git a/src/renderers/js-experimental/ImportMap.ts b/src/renderers/js-experimental/ImportMap.ts index a7d920934..85b73bb7a 100644 --- a/src/renderers/js-experimental/ImportMap.ts +++ b/src/renderers/js-experimental/ImportMap.ts @@ -27,6 +27,7 @@ const DEFAULT_MODULE_MAP: Record = { generatedAccounts: '../accounts', generatedErrors: '../errors', generatedTypes: '../types', + generatedInstructions: '../instructions', }; export class ImportMap { diff --git a/src/renderers/js-experimental/fragments/programInstructions.ts b/src/renderers/js-experimental/fragments/programInstructions.ts index b7fd84846..e5074ec0b 100644 --- a/src/renderers/js-experimental/fragments/programInstructions.ts +++ b/src/renderers/js-experimental/fragments/programInstructions.ts @@ -4,7 +4,6 @@ import { ProgramNode, structTypeNodeFromInstructionArgumentNodes, } from '../../../nodes'; -import { ImportMap } from '../ImportMap'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { Fragment, fragment, mergeFragments } from './common'; import { getDiscriminatorConditionFragment } from './discriminatorCondition'; @@ -30,7 +29,7 @@ export function getProgramInstructionsFragment( [ getProgramInstructionsEnumFragment(scopeWithInstructions), getProgramInstructionsIdentifierFunctionFragment(scopeWithInstructions), - getProgramUnionParsedInstructionTypeFragment(scopeWithInstructions), + getProgramInstructionsParsedUnionTypeFragment(scopeWithInstructions), ], (r) => `${r.join('\n\n')}\n` ); @@ -106,7 +105,7 @@ function getProgramInstructionsIdentifierFunctionFragment( ); } -function getProgramUnionParsedInstructionTypeFragment( +function getProgramInstructionsParsedUnionTypeFragment( scope: Pick & { programNode: ProgramNode; allInstructions: InstructionNode[]; @@ -114,7 +113,7 @@ function getProgramUnionParsedInstructionTypeFragment( ): Fragment { const { programNode, allInstructions, nameApi } = scope; - const programInstructionsType = nameApi.programInstructionsTypeUnion( + const programInstructionsType = nameApi.programInstructionsParsedUnionType( programNode.name ); @@ -132,9 +131,8 @@ function getProgramUnionParsedInstructionTypeFragment( ); return fragment( - `| {instructionType: ${programInstructionsEnum}.${instructionEnumVariant}} & ${parsedInstructionType}`, - new ImportMap().add('../instructions', parsedInstructionType) - ); + `| {instructionType: ${programInstructionsEnum}.${instructionEnumVariant}} & ${parsedInstructionType}` + ).addImports('generatedInstructions', parsedInstructionType); }); return mergeFragments( diff --git a/src/renderers/js-experimental/nameTransformers.ts b/src/renderers/js-experimental/nameTransformers.ts index eff148d62..87a656e31 100644 --- a/src/renderers/js-experimental/nameTransformers.ts +++ b/src/renderers/js-experimental/nameTransformers.ts @@ -67,7 +67,7 @@ export type NameTransformerKey = | 'programInstructionsEnum' | 'programInstructionsEnumVariant' | 'programInstructionsIdentifierFunction' - | 'programInstructionsTypeUnion' + | 'programInstructionsParsedUnionType' | 'programErrorClass' | 'programErrorCodeEnum' | 'programErrorCodeMap' @@ -148,7 +148,7 @@ export const DEFAULT_NAME_TRANSFORMERS: NameTransformers = { programInstructionsEnumVariant: (name) => `${pascalCase(name)}`, programInstructionsIdentifierFunction: (name) => `identify${pascalCase(name)}Instruction`, - programInstructionsTypeUnion: (name) => + programInstructionsParsedUnionType: (name) => `Parsed${pascalCase(name)}Instruction`, programErrorClass: (name) => `${pascalCase(name)}ProgramError`, programErrorCodeEnum: (name) => `${pascalCase(name)}ProgramErrorCode`, diff --git a/test/renderers/js-experimental/programsPage.test.ts b/test/renderers/js-experimental/programsPage.test.ts index 0cac7f23f..bc80188a6 100644 --- a/test/renderers/js-experimental/programsPage.test.ts +++ b/test/renderers/js-experimental/programsPage.test.ts @@ -236,3 +236,27 @@ test('it checks the discriminator of sub-instructions before their parents.', (t `if (memcmp(data, getU8Encoder().encode(1), 0)) { return SplTokenInstruction.MintTokens; }`, ]); }); + +test('it renders a parsed union type of all available instructions for a program', (t) => { + // Given the following program. + const node = programNode({ + name: 'splToken', + publicKey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', + instructions: [ + instructionNode({ name: 'mintTokens' }), + instructionNode({ name: 'transferTokens' }), + instructionNode({ name: 'updateAuthority' }), + ], + }); + + // When we render it. + const renderMap = visit(node, getRenderMapVisitor()); + + // Then we expect the following program instruction enum. + renderMapContains(t, renderMap, 'programs/splToken.ts', [ + 'export type ParsedSplTokenInstruction=', + '|({instructionType: SplTokenInstruction.MintTokens;} & ParsedMintTokensInstruction)', + '|({instructionType: SplTokenInstruction.TransferTokens;} & ParsedTransferTokensInstruction)', + '|({instructionType: SplTokenInstruction.UpdateAuthority;} & ParsedUpdateAuthorityInstruction)', + ]); +});