UNPKG

@honeycomb-protocol/solita

Version:

Generates SDK API from solana contract IDL.

147 lines (145 loc) 5.88 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.renderDataEnumRecord = exports.renderTypeDataEnumBeet = void 0; const camelcase_1 = __importDefault(require("camelcase")); const types_1 = require("./types"); const utils_1 = require("./utils"); /** * Renders union type and related methods for Rust data enum. */ function renderTypeDataEnumBeet(args) { const { typeMapper, dataEnum, beetVarName, generics = [] } = args; const { enumRecordName, typeNameWithGenerics: typeName, renderBeetExport, } = (0, utils_1.genericsToTokens)(args.typeName, generics); const renderedVariants = dataEnum.variants.map((variant) => { const tm = typeMapper.clone(); const beet = renderVariant(tm, enumRecordName, variant); typeMapper.syncUp(tm); return { beet, usedFixableSerde: tm.usedFixableSerde }; }); const renderedBeets = renderedVariants .map((variant) => variant.beet) .join(',\n'); // The size of a data enum is considered non-deterministic even though exceptions // exist, i.e. when they have a single variant const beetType = 'FixableBeet'; typeMapper.usedFixableSerde = true; if (generics.length) { return ` ${renderBeetExport(beetVarName)}${types_1.BEET_EXPORT_NAME}.dataEnum<${enumRecordName}>([${renderedBeets}]) as ${types_1.BEET_EXPORT_NAME}.${beetType}<${typeName}, ${typeName}> `; } return ` const variants: beet.DataEnumBeet<${enumRecordName}>[] = []; ${renderBeetExport(beetVarName)}${types_1.BEET_EXPORT_NAME}.dataEnum<${enumRecordName}>(variants) as ${types_1.BEET_EXPORT_NAME}.${beetType}<${typeName}, ${typeName}> variants.push(${renderedBeets}) `; } exports.renderTypeDataEnumBeet = renderTypeDataEnumBeet; function renderVariant(typeMapper, enumRecordName, variant) { const typeName = `${enumRecordName}["${variant.name}"]`; if ((0, types_1.isDataEnumVariantWithNamedFields)(variant)) { // Variant with named fields is represented as a struct const mappedFields = typeMapper.mapSerdeFields(variant.fields); const fieldDecls = mappedFields .map((f) => { const fieldName = (0, camelcase_1.default)(f.name); return ` ['${fieldName}', ${f.type}]`; }) .join(',\n '); const beetArgsStructType = typeMapper.usedFixableSerde ? 'FixableBeetArgsStruct' : 'BeetArgsStruct'; const beet = ` [ '${variant.name}', new ${types_1.BEET_EXPORT_NAME}.${beetArgsStructType}<${typeName}>( [ ${fieldDecls} ], '${typeName}' )]`; return beet; } else if ((0, types_1.isDataEnumVariant)(variant)) { // Variant with unnamed fields is represented as a tuple const tuple = { tuple: variant.fields }; const fieldDecls = typeMapper.mapSerde(tuple); const beetArgsStructType = typeMapper.usedFixableSerde ? 'FixableBeetArgsStruct' : 'BeetArgsStruct'; const beet = `[ '${variant.name}', new ${types_1.BEET_EXPORT_NAME}.${beetArgsStructType}<${typeName}>( [[ 'fields', ${fieldDecls} ]], '${typeName}') ]`; return beet; } else { // Scalar Variant that's part of a Data Enum const beet = `[ '${variant.name}', ${types_1.BEET_EXPORT_NAME}.unit ]`; return beet; } } function renderDataEnumRecord(typeMapper, typeName, variants, generics = []) { const { typeNameWithGenerics, enumRecordName, genericsDefaults } = (0, utils_1.genericsToTokens)(typeName, generics); const renderedVariants = variants.map((variant) => { let fields; if ((0, types_1.isDataEnumVariantWithNamedFields)(variant)) { fields = variant.fields.map((f) => { const typescriptType = typeMapper.map(f.type, f.name); const fieldName = (0, camelcase_1.default)(f.name); return `${fieldName}: ${typescriptType}`; }); return ` ${variant.name}: { ${fields.join(', ')} }`; } else if ((0, types_1.isDataEnumVariant)(variant)) { fields = variant.fields.map((type, idx) => { const ty = (0, types_1.isIdlFieldType)(type) ? type.type : type; return typeMapper.map(ty, `${variant.name}[${idx}]`); }); return ` ${variant.name}: { fields: [ ${fields.join(', ')} ] }`; } else { return ` ${variant.name}: void /* scalar variant */`; } }); const renderedGuards = variants.map((variant) => { const v = variant.name; return `export const is${typeName}${v} = ${genericsDefaults}( x: ${typeNameWithGenerics} ): x is ${typeNameWithGenerics} & { __kind: '${v}' } => x.__kind === '${v}'`; }); return ` /** * This type is used to derive the {@link ${typeName}} type as well as the de/serializer. * However don't refer to it in your code but use the {@link ${typeName}} type instead. * * @category userTypes * @category enums * @category generated * @private */ export type ${enumRecordName} = { ${renderedVariants.join(',\n ')} } /** * Union type respresenting the ${typeName} data enum defined in Rust. * * NOTE: that it includes a \`__kind\` property which allows to narrow types in * switch/if statements. * Additionally \`is${typeName}*\` type guards are exposed below to narrow to a specific variant. * * @category userTypes * @category enums * @category generated */ export type ${typeNameWithGenerics} = beet.DataEnumKeyAsKind<${enumRecordName}> ${renderedGuards.join('\n')} `.trim(); } exports.renderDataEnumRecord = renderDataEnumRecord; //# sourceMappingURL=render-data-enum.js.map