Skip to content

Commit

Permalink
Update enums codecs from latest Web3.js version (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
lorisleiva authored Mar 27, 2024
1 parent bc6e82c commit 38943c1
Show file tree
Hide file tree
Showing 34 changed files with 375 additions and 309 deletions.
5 changes: 5 additions & 0 deletions .changeset/poor-lions-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@metaplex-foundation/kinobi": minor
---

Update enums codecs from latest Web3.js version on the JS experimental renderer
2 changes: 1 addition & 1 deletion src/renderers/js-experimental/fragments/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export * from './programErrors';
export * from './programInstructions';
export * from './type';
export * from './typeCodec';
export * from './typeDataEnumHelpers';
export * from './typeDecoder';
export * from './typeDiscriminatedUnionHelpers';
export * from './typeEncoder';
export * from './typeWithCodec';
23 changes: 0 additions & 23 deletions src/renderers/js-experimental/fragments/typeDataEnumHelpers.njk

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Data Enum Helpers.
{% for variant in typeNode.variants %}
{% if variant.kind === 'enumStructVariantTypeNode' %}
export function {{ discriminatedUnionFunction }}(kind: '{{ getVariant(variant.name) }}', data: GetDiscriminatedUnionVariantContent<{{ looseName }}, '__kind', '{{ getVariant(variant.name) }}'>): GetDiscriminatedUnionVariant<{{ looseName }}, '__kind', '{{ getVariant(variant.name) }}'>;
{% elif variant.kind === 'enumTupleVariantTypeNode' %}
export function {{ discriminatedUnionFunction }}(kind: '{{ getVariant(variant.name) }}', data: GetDiscriminatedUnionVariantContent<{{ looseName }}, '__kind', '{{ getVariant(variant.name) }}'>['fields']): GetDiscriminatedUnionVariant<{{ looseName }}, '__kind', '{{ getVariant(variant.name) }}'>;
{% else %}
export function {{ discriminatedUnionFunction }}(kind: '{{ getVariant(variant.name) }}'): GetDiscriminatedUnionVariant<{{ looseName }}, '__kind', '{{ getVariant(variant.name) }}'>;
{% endif %}
{% endfor %}
export function {{ discriminatedUnionFunction }}<K extends {{ looseName }}['{{ discriminatedUnionDiscriminator }}'], Data>(
kind: K,
data?: Data,
) {
return Array.isArray(data) ? { {{ discriminatedUnionDiscriminator }}: kind, fields: data } : { {{ discriminatedUnionDiscriminator }}: kind, ...(data ?? {}) };
}

export function {{ isDiscriminatedUnionFunction }}<K extends {{ strictName }}['{{ discriminatedUnionDiscriminator }}']>(
kind: K,
value: {{ strictName }},
): value is {{ strictName }} & { {{ discriminatedUnionDiscriminator }}: K } {
return value.{{ discriminatedUnionDiscriminator }} === kind;
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,31 @@ import { TypeNode, isDataEnum, isNode } from '../../../nodes';
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
import { Fragment, fragment, fragmentFromTemplate } from './common';

export function getTypeDataEnumHelpersFragment(
export function getTypeDiscriminatedUnionHelpersFragment(
scope: Pick<GlobalFragmentScope, 'nameApi'> & {
name: string;
typeNode: TypeNode;
}
): Fragment {
const { name, typeNode, nameApi } = scope;
const isDataEnumNode =
const isDiscriminatedUnion =
isNode(typeNode, 'enumTypeNode') && isDataEnum(typeNode);

if (!isDataEnumNode) {
if (!isDiscriminatedUnion) {
return fragment('');
}

return fragmentFromTemplate('typeDataEnumHelpers.njk', {
return fragmentFromTemplate('typeDiscriminatedUnionHelpers.njk', {
strictName: nameApi.dataType(name),
looseName: nameApi.dataArgsType(name),
dataEnumDiscriminator: nameApi.dataEnumDiscriminator(name),
getVariant: (variant: string) => nameApi.dataEnumVariant(variant),
dataEnumFunction: nameApi.dataEnumFunction(name),
isDataEnumFunction: nameApi.isDataEnumFunction(name),
discriminatedUnionDiscriminator:
nameApi.discriminatedUnionDiscriminator(name),
getVariant: (variant: string) => nameApi.discriminatedUnionVariant(variant),
discriminatedUnionFunction: nameApi.discriminatedUnionFunction(name),
isDiscriminatedUnionFunction: nameApi.isDiscriminatedUnionFunction(name),
typeNode,
}).addImports('solanaCodecsDataStructures', [
'GetDataEnumKindContent',
'GetDataEnumKind',
'GetDiscriminatedUnionVariantContent',
'GetDiscriminatedUnionVariant',
]);
}
13 changes: 8 additions & 5 deletions src/renderers/js-experimental/getRenderMapVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import {
getProgramErrorsFragment,
getProgramFragment,
getProgramInstructionsFragment,
getTypeDataEnumHelpersFragment,
getTypeDiscriminatedUnionHelpersFragment,
getTypeWithCodecFragment,
} from './fragments';
import {
Expand Down Expand Up @@ -447,10 +447,13 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) {
};

const typeWithCodecFragment = getTypeWithCodecFragment(scope);
const typeDataEnumHelpersFragment =
getTypeDataEnumHelpersFragment(scope);
const typeDiscriminatedUnionHelpersFragment =
getTypeDiscriminatedUnionHelpersFragment(scope);
const imports = new ImportMap()
.mergeWith(typeWithCodecFragment, typeDataEnumHelpersFragment)
.mergeWith(
typeWithCodecFragment,
typeDiscriminatedUnionHelpersFragment
)
.remove('generatedTypes', [
nameApi.dataType(node.name),
nameApi.dataArgsType(node.name),
Expand All @@ -467,7 +470,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) {
generatedTypes: '.',
}),
typeWithCodecFragment,
typeDataEnumHelpersFragment,
typeDiscriminatedUnionHelpersFragment,
})
);
},
Expand Down
44 changes: 28 additions & 16 deletions src/renderers/js-experimental/getTypeManifestVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,28 +171,28 @@ export function getTypeManifestVisitor(input: {
);
}
const variantNames = enumType.variants.map(({ name }) =>
nameApi.scalarEnumVariant(name)
nameApi.enumVariant(name)
);
return {
isEnum: true,
strictType: fragment(`{ ${variantNames.join(', ')} }`),
looseType: fragment(`{ ${variantNames.join(', ')} }`),
encoder: fragment(
`getScalarEnumEncoder(${
`getEnumEncoder(${
currentParentName.strict + encoderOptionsAsString
})`,
encoderImports.add(
'solanaCodecsDataStructures',
'getScalarEnumEncoder'
'getEnumEncoder'
)
),
decoder: fragment(
`getScalarEnumDecoder(${
`getEnumDecoder(${
currentParentName.strict + decoderOptionsAsString
})`,
decoderImports.add(
'solanaCodecsDataStructures',
'getScalarEnumDecoder'
'getEnumDecoder'
)
),
};
Expand All @@ -205,24 +205,32 @@ export function getTypeManifestVisitor(input: {
);
mergedManifest.encoder
.mapRender(
(r) => `getDataEnumEncoder([${r}]${encoderOptionsAsString})`
(r) =>
`getDiscriminatedUnionEncoder([${r}]${encoderOptionsAsString})`
)
.mergeImportsWith(encoderImports)
.addImports('solanaCodecsDataStructures', ['getDataEnumEncoder']);
.addImports('solanaCodecsDataStructures', [
'getDiscriminatedUnionEncoder',
]);
mergedManifest.decoder
.mapRender(
(r) => `getDataEnumDecoder([${r}]${decoderOptionsAsString})`
(r) =>
`getDiscriminatedUnionDecoder([${r}]${decoderOptionsAsString})`
)
.mergeImportsWith(decoderImports)
.addImports('solanaCodecsDataStructures', ['getDataEnumDecoder']);
.addImports('solanaCodecsDataStructures', [
'getDiscriminatedUnionDecoder',
]);
return mergedManifest;
},

visitEnumEmptyVariantType(enumEmptyVariantType) {
const discriminator = nameApi.dataEnumDiscriminator(
const discriminator = nameApi.discriminatedUnionDiscriminator(
enumEmptyVariantType.name
);
const name = nameApi.discriminatedUnionVariant(
enumEmptyVariantType.name
);
const name = nameApi.dataEnumVariant(enumEmptyVariantType.name);
const kindAttribute = `${discriminator}: "${name}"`;
return {
isEnum: false,
Expand All @@ -240,10 +248,12 @@ export function getTypeManifestVisitor(input: {
},

visitEnumStructVariantType(enumStructVariantType, { self }) {
const discriminator = nameApi.dataEnumDiscriminator(
const discriminator = nameApi.discriminatedUnionDiscriminator(
enumStructVariantType.name
);
const name = nameApi.discriminatedUnionVariant(
enumStructVariantType.name
);
const name = nameApi.dataEnumVariant(enumStructVariantType.name);
const kindAttribute = `${discriminator}: "${name}"`;
const structManifest = visit(enumStructVariantType.struct, self);
structManifest.strictType.mapRender(
Expand All @@ -258,10 +268,12 @@ export function getTypeManifestVisitor(input: {
},

visitEnumTupleVariantType(enumTupleVariantType, { self }) {
const discriminator = nameApi.dataEnumDiscriminator(
const discriminator = nameApi.discriminatedUnionDiscriminator(
enumTupleVariantType.name
);
const name = nameApi.discriminatedUnionVariant(
enumTupleVariantType.name
);
const name = nameApi.dataEnumVariant(enumTupleVariantType.name);
const kindAttribute = `${discriminator}: "${name}"`;
const struct = structTypeNode([
structFieldTypeNode({
Expand Down Expand Up @@ -463,7 +475,7 @@ export function getTypeManifestVisitor(input: {
const items = tupleType.items.map((item) => visit(item, self));
const mergedManifest = mergeManifests(
items,
(types) => `[${types.join(', ')}]`,
(types) => `readonly [${types.join(', ')}]`,
(codecs) => `[${codecs.join(', ')}]`
);
mergedManifest.encoder
Expand Down
20 changes: 10 additions & 10 deletions src/renderers/js-experimental/nameTransformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ export type NameTransformerKey =
| 'accountFetchFromSeedsFunction'
| 'accountFetchMaybeFromSeedsFunction'
| 'accountGetSizeFunction'
| 'scalarEnumVariant'
| 'dataEnumDiscriminator'
| 'dataEnumVariant'
| 'dataEnumFunction'
| 'isDataEnumFunction'
| 'enumVariant'
| 'discriminatedUnionDiscriminator'
| 'discriminatedUnionVariant'
| 'discriminatedUnionFunction'
| 'isDiscriminatedUnionFunction'
| 'instructionAsyncInputType'
| 'instructionSyncInputType'
| 'instructionType'
Expand Down Expand Up @@ -111,11 +111,11 @@ export const DEFAULT_NAME_TRANSFORMERS: NameTransformers = {
accountFetchMaybeFromSeedsFunction: (name) =>
`fetchMaybe${pascalCase(name)}FromSeeds`,
accountGetSizeFunction: (name) => `get${pascalCase(name)}Size`,
scalarEnumVariant: (name) => `${pascalCase(name)}`,
dataEnumDiscriminator: () => '__kind',
dataEnumVariant: (name) => `${pascalCase(name)}`,
dataEnumFunction: (name) => `${camelCase(name)}`,
isDataEnumFunction: (name) => `is${pascalCase(name)}`,
enumVariant: (name) => `${pascalCase(name)}`,
discriminatedUnionDiscriminator: () => '__kind',
discriminatedUnionVariant: (name) => `${pascalCase(name)}`,
discriminatedUnionFunction: (name) => `${camelCase(name)}`,
isDiscriminatedUnionFunction: (name) => `is${pascalCase(name)}`,
instructionAsyncInputType: (name) => `${pascalCase(name)}AsyncInput`,
instructionSyncInputType: (name) => `${pascalCase(name)}Input`,
instructionType: (name) => `${pascalCase(name)}Instruction`,
Expand Down
6 changes: 3 additions & 3 deletions src/renderers/js-experimental/renderValueNodeVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export function renderValueNodeVisitor(input: {
},
visitEnumValue(node) {
const enumName = nameApi.dataType(node.enum.name);
const enumFunction = nameApi.dataEnumFunction(node.enum.name);
const enumFunction = nameApi.discriminatedUnionFunction(node.enum.name);
const importFrom = node.enum.importFrom ?? 'generatedTypes';

const enumNode = linkables.get(node.enum)?.type;
Expand All @@ -34,14 +34,14 @@ export function renderValueNodeVisitor(input: {
: !nonScalarEnums.includes(node.enum.name);

if (!node.value && isScalar) {
const variantName = nameApi.scalarEnumVariant(node.variant);
const variantName = nameApi.enumVariant(node.variant);
return fragment(`${enumName}.${variantName}`).addImports(
importFrom,
enumName
);
}

const variantName = nameApi.dataEnumVariant(node.variant);
const variantName = nameApi.discriminatedUnionVariant(node.variant);
if (!node.value) {
return fragment(`${enumFunction}('${variantName}')`).addImports(
importFrom,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
{{ imports }}

{{ typeWithCodecFragment }}
{{ typeDataEnumHelpersFragment }}
{{ typeDiscriminatedUnionHelpersFragment }}
{% endblock %}
12 changes: 6 additions & 6 deletions test/packages/js-experimental/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
"author": "",
"license": "ISC",
"dependencies": {
"@solana/accounts": "2.0.0-experimental.a7a613a",
"@solana/addresses": "2.0.0-experimental.a7a613a",
"@solana/codecs": "2.0.0-experimental.a7a613a",
"@solana/instructions": "2.0.0-experimental.a7a613a",
"@solana/programs": "2.0.0-experimental.a7a613a",
"@solana/signers": "2.0.0-experimental.a7a613a"
"@solana/accounts": "2.0.0-preview.1.20240327135415.5b21c65e6779dd873d0a2d5ba2c7dd1ca607e2be",
"@solana/addresses": "2.0.0-preview.1.20240327135415.5b21c65e6779dd873d0a2d5ba2c7dd1ca607e2be",
"@solana/codecs": "2.0.0-preview.1.20240327135415.5b21c65e6779dd873d0a2d5ba2c7dd1ca607e2be",
"@solana/instructions": "2.0.0-preview.1.20240327135415.5b21c65e6779dd873d0a2d5ba2c7dd1ca607e2be",
"@solana/programs": "2.0.0-preview.1.20240327135415.5b21c65e6779dd873d0a2d5ba2c7dd1ca607e2be",
"@solana/signers": "2.0.0-preview.1.20240327135415.5b21c65e6779dd873d0a2d5ba2c7dd1ca607e2be"
},
"devDependencies": {
"@solana/eslint-config-solana": "^3.0.3",
Expand Down
Loading

0 comments on commit 38943c1

Please sign in to comment.