@fuel-ts/abi-typegen
Version:
Generates Typescript definitions from Sway ABI Json files
1,718 lines (1,604 loc) • 58.4 kB
JavaScript
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
// src/runTypegen.ts
import { ErrorCode as ErrorCode10, FuelError as FuelError9 } from "@fuel-ts/errors";
import { versions as builtinVersions } from "@fuel-ts/versions";
import { readFileSync as readFileSync3, writeFileSync } from "fs";
import { globSync } from "glob";
import { mkdirp } from "mkdirp";
import { basename } from "path";
import { rimrafSync } from "rimraf";
// src/AbiTypeGen.ts
import { ErrorCode as ErrorCode9, FuelError as FuelError8 } from "@fuel-ts/errors";
// src/abi/Abi.ts
import { ErrorCode as ErrorCode5, FuelError as FuelError4 } from "@fuel-ts/errors";
import { normalizeString } from "@fuel-ts/utils";
// src/abi/errors/ErrorCode.ts
var ErrorCode = class {
static {
__name(this, "ErrorCode");
}
code;
value;
constructor(params) {
this.code = params.code;
this.value = params.value;
}
};
// src/utils/makeErrorCodes.ts
function makeErrorCode(params) {
return new ErrorCode(params);
}
__name(makeErrorCode, "makeErrorCode");
// src/utils/parseErrorCodes.ts
function parseErrorCodes(params) {
const { rawErrorCodes } = params;
const errorCodes = Object.entries(rawErrorCodes ?? {}).map(
([code, value]) => makeErrorCode({ code, value })
);
return errorCodes;
}
__name(parseErrorCodes, "parseErrorCodes");
// src/abi/types/AType.ts
var AType = class {
static {
__name(this, "AType");
}
rawAbiType;
attributes;
requiredFuelsMembersImports;
constructor(params) {
this.rawAbiType = params.rawAbiType;
this.attributes = {
inputLabel: "unknown",
outputLabel: "unknown"
};
this.requiredFuelsMembersImports = [];
}
};
// src/abi/types/EmptyType.ts
var EmptyType = class _EmptyType extends AType {
static {
__name(this, "EmptyType");
}
static swayType = "()";
name = "empty";
static MATCH_REGEX = /^\(\)$/m;
constructor(params) {
super(params);
this.attributes = {
inputLabel: "undefined",
outputLabel: "void"
};
}
static isSuitableFor(params) {
return _EmptyType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
return this.attributes;
}
};
// src/abi/types/OptionType.ts
var OptionType = class _OptionType extends AType {
static {
__name(this, "OptionType");
}
static swayType = "enum Option";
name = "option";
static MATCH_REGEX = /^enum (std::option::)?Option$/m;
static isSuitableFor(params) {
return _OptionType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
this.attributes = {
inputLabel: `Option`,
outputLabel: `Option`
};
return this.attributes;
}
};
// src/utils/findType.ts
import { ErrorCode as ErrorCode2, FuelError } from "@fuel-ts/errors";
function findType(params) {
const { types, typeId } = params;
const foundType = types.find(({ rawAbiType: { typeId: tid } }) => tid === typeId);
if (!foundType) {
throw new FuelError(ErrorCode2.TYPE_ID_NOT_FOUND, `Type ID not found: ${typeId}.`);
}
foundType.parseComponentsAttributes({ types });
return foundType;
}
__name(findType, "findType");
// src/utils/getFunctionInputs.ts
var getFunctionInputs = /* @__PURE__ */ __name((params) => {
const { types, inputs } = params;
let isMandatory = false;
return inputs.reduceRight((result, input) => {
const type = findType({ types, typeId: input.type });
const isTypeMandatory = !EmptyType.isSuitableFor({ type: type.rawAbiType.type }) && !OptionType.isSuitableFor({ type: type.rawAbiType.type });
isMandatory = isMandatory || isTypeMandatory;
return [{ ...input, isOptional: !isMandatory }, ...result];
}, []);
}, "getFunctionInputs");
// src/utils/parseTypeArguments.ts
function parseTypeArguments(params) {
const { types, typeArguments, parentTypeId, target } = params;
const attributeKey = `${target}Label`;
const buffer = [];
let parentType;
let parentLabel;
if (parentTypeId !== void 0) {
parentType = findType({ types, typeId: parentTypeId });
parentLabel = parentType.attributes[attributeKey];
}
typeArguments.forEach((typeArgument) => {
const currentTypeId = typeArgument.type;
const currentType = findType({ types, typeId: currentTypeId });
const currentLabel = currentType.attributes[attributeKey];
if (typeArgument.typeArguments) {
const nestedParsed = parseTypeArguments({
types,
target,
parentTypeId: typeArgument.type,
typeArguments: typeArgument.typeArguments
});
buffer.push(nestedParsed);
} else {
buffer.push(`${currentLabel}`);
}
});
let output = buffer.join(", ");
if (parentLabel) {
output = `${parentLabel}<${output}>`;
}
return output;
}
__name(parseTypeArguments, "parseTypeArguments");
// src/utils/getTypeDeclaration.ts
function resolveInputLabel(types, typeId, typeArguments) {
const type = findType({ types, typeId });
let typeDecl;
if (typeArguments?.length) {
typeDecl = parseTypeArguments({
types,
target: "input" /* INPUT */,
parentTypeId: typeId,
typeArguments
});
} else {
typeDecl = type.attributes.inputLabel;
}
return typeDecl;
}
__name(resolveInputLabel, "resolveInputLabel");
// src/abi/functions/Function.ts
var Function = class {
static {
__name(this, "Function");
}
name;
types;
rawAbiFunction;
attributes;
constructor(params) {
this.rawAbiFunction = params.rawAbiFunction;
this.types = params.types;
this.name = params.rawAbiFunction.name;
this.attributes = {
inputs: this.bundleInputTypes(),
output: this.bundleOutputTypes(),
prefixedInputs: this.bundleInputTypes(true)
};
}
bundleInputTypes(shouldPrefixParams = false) {
const { types } = this;
const inputs = getFunctionInputs({ types, inputs: this.rawAbiFunction.inputs }).map(
({ isOptional, ...input }) => {
const { name, type: typeId, typeArguments } = input;
const typeDecl = resolveInputLabel(types, typeId, typeArguments);
if (shouldPrefixParams) {
const optionalSuffix = isOptional ? "?" : "";
return `${name}${optionalSuffix}: ${typeDecl}`;
}
return typeDecl;
}
);
return inputs.join(", ");
}
bundleOutputTypes() {
return parseTypeArguments({
types: this.types,
target: "output" /* OUTPUT */,
typeArguments: [this.rawAbiFunction.output]
});
}
getDeclaration() {
const { name } = this;
const { prefixedInputs, output } = this.attributes;
const decl = `${name}: InvokeFunction<[${prefixedInputs}], ${output}>`;
return decl;
}
};
// src/utils/makeFunction.ts
function makeFunction(params) {
const { types, rawAbiFunction } = params;
return new Function({ types, rawAbiFunction });
}
__name(makeFunction, "makeFunction");
// src/utils/parseFunctions.ts
function parseFunctions(params) {
const { types, rawAbiFunctions } = params;
const functions = rawAbiFunctions.map(
(rawAbiFunction) => makeFunction({ types, rawAbiFunction })
);
return functions;
}
__name(parseFunctions, "parseFunctions");
// src/utils/makeType.ts
import { ErrorCode as ErrorCode4, FuelError as FuelError3 } from "@fuel-ts/errors";
// src/abi/types/ArrayType.ts
var ArrayType = class _ArrayType extends AType {
static {
__name(this, "ArrayType");
}
// Note: the array length expressed in '; 2]' could be any length
static swayType = "[_; 2]";
name = "array";
static MATCH_REGEX = /^\[_; ([0-9]+)\]$/m;
static isSuitableFor(params) {
return _ArrayType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(params) {
const { types } = params;
const { type } = this.rawAbiType;
const arrayLen = Number(type.match(_ArrayType.MATCH_REGEX)?.[1]);
const inputs = [];
const outputs = [];
this.rawAbiType.components?.forEach((component) => {
const { type: typeId, typeArguments } = component;
if (!typeArguments) {
const { attributes } = findType({ types, typeId });
inputs.push(attributes.inputLabel);
outputs.push(attributes.outputLabel);
} else {
const inputLabel = parseTypeArguments({
types,
typeArguments,
parentTypeId: typeId,
target: "input" /* INPUT */
});
const outputLabel = parseTypeArguments({
types,
typeArguments,
parentTypeId: typeId,
target: "output" /* OUTPUT */
});
inputs.push(inputLabel);
outputs.push(outputLabel);
}
});
const inputTypes = Array(arrayLen).fill(inputs[0]).join(", ");
const outputTypes = Array(arrayLen).fill(outputs[0]).join(", ");
this.attributes = {
inputLabel: `[${inputTypes}]`,
outputLabel: `[${outputTypes}]`
};
return this.attributes;
}
};
// src/abi/types/StrType.ts
var StrType = class _StrType extends AType {
static {
__name(this, "StrType");
}
// Note: the str length expressed in '[3]' could be any length
static swayType = "str[3]";
name = "str";
static MATCH_REGEX = /^str\[(.+)\]$/m;
static isSuitableFor(params) {
return _StrType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
this.attributes = {
inputLabel: "string",
outputLabel: "string"
};
return this.attributes;
}
};
// src/abi/types/B256Type.ts
var B256Type = class _B256Type extends StrType {
static {
__name(this, "B256Type");
}
static swayType = "b256";
name = "b256";
static MATCH_REGEX = /^b256$/m;
static isSuitableFor(params) {
return _B256Type.MATCH_REGEX.test(params.type);
}
};
// src/abi/types/B512Type.ts
var B512Type = class _B512Type extends B256Type {
static {
__name(this, "B512Type");
}
static swayType = "struct B512";
name = "b512";
static MATCH_REGEX = /^struct (std::b512::)?B512$/m;
static isSuitableFor(params) {
return _B512Type.MATCH_REGEX.test(params.type);
}
};
// src/abi/types/BoolType.ts
var BoolType = class _BoolType extends AType {
static {
__name(this, "BoolType");
}
static swayType = "bool";
name = "bool";
static MATCH_REGEX = /^bool$/m;
static isSuitableFor(params) {
return _BoolType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
this.attributes = {
inputLabel: "boolean",
outputLabel: "boolean"
};
return this.attributes;
}
};
// src/abi/types/BytesType.ts
var BytesType = class _BytesType extends ArrayType {
static {
__name(this, "BytesType");
}
static swayType = "struct Bytes";
name = "bytes";
static MATCH_REGEX = /^struct (std::bytes::)?Bytes/m;
static isSuitableFor(params) {
return _BytesType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
const capitalizedName = "Bytes";
this.attributes = {
inputLabel: capitalizedName,
outputLabel: capitalizedName
};
this.requiredFuelsMembersImports = [capitalizedName];
return this.attributes;
}
};
// src/utils/extractStructName.ts
import { ErrorCode as ErrorCode3, FuelError as FuelError2 } from "@fuel-ts/errors";
function extractStructName(params) {
const { rawAbiType, regex } = params;
const matches = rawAbiType.type.match(regex);
const match = matches?.[2] ?? matches?.[1];
if (!match) {
let errorMessage = `Couldn't extract struct name with: '${regex}'.
`;
errorMessage += `Check your JSON ABI.
[source]
`;
errorMessage += `${JSON.stringify(rawAbiType, null, 2)}`;
throw new FuelError2(ErrorCode3.JSON_ABI_ERROR, errorMessage);
}
return match;
}
__name(extractStructName, "extractStructName");
// src/abi/types/ResultType.ts
var ResultType = class _ResultType extends AType {
static {
__name(this, "ResultType");
}
static swayType = "enum Result";
name = "result";
static MATCH_REGEX = /^enum (std::result::)?Result$/m;
static isSuitableFor(params) {
return _ResultType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
this.attributes = {
inputLabel: `Result`,
outputLabel: `Result`
};
return this.attributes;
}
};
// src/abi/types/EnumType.ts
var EnumType = class _EnumType extends AType {
static {
__name(this, "EnumType");
}
static swayType = "enum MyEnumName";
name = "enum";
static MATCH_REGEX = /^enum (.+::)?(.+)$/m;
static IGNORE_REGEXES = [OptionType.MATCH_REGEX, ResultType.MATCH_REGEX];
static isSuitableFor(params) {
const isAMatch = _EnumType.MATCH_REGEX.test(params.type);
const shouldBeIgnored = _EnumType.IGNORE_REGEXES.some((r) => r.test(params.type));
return isAMatch && !shouldBeIgnored;
}
parseComponentsAttributes(_params) {
const structName = this.getStructName();
this.attributes = {
structName,
inputLabel: `${structName}Input`,
outputLabel: `${structName}Output`
};
return this.attributes;
}
getStructName() {
const name = extractStructName({
rawAbiType: this.rawAbiType,
regex: _EnumType.MATCH_REGEX
});
return name;
}
getNativeEnum(params) {
const { types } = params;
const typeHash = types.reduce(
(hash, row) => ({
...hash,
[row.rawAbiType.typeId]: row.rawAbiType.type
}),
{}
);
const { components } = this.rawAbiType;
const enumComponents = components;
if (!enumComponents.every(({ type }) => typeHash[type] === EmptyType.swayType)) {
return void 0;
}
return enumComponents.map(({ name }) => `${name} = '${name}'`).join(", ");
}
getStructContents(params) {
const { types, target } = params;
const { components } = this.rawAbiType;
const enumComponents = components;
const attributeKey = `${target}Label`;
const contents = enumComponents.map((component) => {
const { name, type: typeId, typeArguments } = component;
if (typeId === 0) {
return `${name}: []`;
}
const type = findType({ types, typeId });
let typeDecl;
if (typeArguments) {
typeDecl = parseTypeArguments({
types,
target,
parentTypeId: typeId,
typeArguments
});
} else {
typeDecl = type.attributes[attributeKey];
}
return `${name}: ${typeDecl}`;
});
return contents.join(", ");
}
getStructDeclaration(params) {
const { types } = params;
const { typeParameters } = this.rawAbiType;
if (typeParameters) {
const structs = typeParameters.map((typeId) => findType({ types, typeId }));
const labels = structs.map(({ attributes: { inputLabel } }) => inputLabel);
return `<${labels.join(", ")}>`;
}
return "";
}
};
// src/abi/types/EvmAddressType.ts
var EvmAddressType = class _EvmAddressType extends AType {
static {
__name(this, "EvmAddressType");
}
static swayType = "struct EvmAddress";
name = "evmAddress";
static MATCH_REGEX = /^struct (std::vm::evm::evm_address::)?EvmAddress$/m;
static isSuitableFor(params) {
return _EvmAddressType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
const capitalizedName = "EvmAddress";
this.attributes = {
inputLabel: capitalizedName,
outputLabel: capitalizedName
};
this.requiredFuelsMembersImports = [capitalizedName];
return this.attributes;
}
};
// src/abi/types/GenericType.ts
var GenericType = class _GenericType extends AType {
static {
__name(this, "GenericType");
}
static swayType = "generic T";
name = "generic";
static MATCH_REGEX = /^generic ([^\s]+)$/m;
static isSuitableFor(params) {
return _GenericType.MATCH_REGEX.test(params.type);
}
getStructName() {
const name = extractStructName({
rawAbiType: this.rawAbiType,
regex: _GenericType.MATCH_REGEX
});
return name;
}
parseComponentsAttributes(_params) {
const label = this.getStructName();
this.attributes = {
inputLabel: label,
outputLabel: label
};
return this.attributes;
}
};
// src/abi/types/U8Type.ts
var U8Type = class _U8Type extends AType {
static {
__name(this, "U8Type");
}
static swayType = "u8";
name = "u8";
static MATCH_REGEX = /^u8$/m;
constructor(params) {
super(params);
this.attributes = {
inputLabel: `BigNumberish`,
outputLabel: `number`
};
this.requiredFuelsMembersImports = [this.attributes.inputLabel];
}
static isSuitableFor(params) {
return _U8Type.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
return this.attributes;
}
};
// src/abi/types/U64Type.ts
var U64Type = class _U64Type extends U8Type {
static {
__name(this, "U64Type");
}
static swayType = "u64";
name = "u64";
static MATCH_REGEX = /^u64$/m;
parseComponentsAttributes(_params) {
this.attributes = {
inputLabel: `BigNumberish`,
outputLabel: `BN`
};
this.requiredFuelsMembersImports = Object.values(this.attributes);
return this.attributes;
}
static isSuitableFor(params) {
return _U64Type.MATCH_REGEX.test(params.type);
}
};
// src/abi/types/RawUntypedPtr.ts
var RawUntypedPtr = class _RawUntypedPtr extends U64Type {
static {
__name(this, "RawUntypedPtr");
}
static swayType = "raw untyped ptr";
name = "rawUntypedPtr";
static MATCH_REGEX = /^raw untyped ptr$/m;
static isSuitableFor(params) {
return _RawUntypedPtr.MATCH_REGEX.test(params.type);
}
};
// src/abi/types/RawUntypedSlice.ts
var RawUntypedSlice = class _RawUntypedSlice extends ArrayType {
static {
__name(this, "RawUntypedSlice");
}
static swayType = "raw untyped slice";
name = "rawUntypedSlice";
static MATCH_REGEX = /^raw untyped slice$/m;
static isSuitableFor(params) {
return _RawUntypedSlice.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
const capitalizedName = "RawSlice";
this.attributes = {
inputLabel: capitalizedName,
outputLabel: capitalizedName
};
this.requiredFuelsMembersImports = [capitalizedName];
return this.attributes;
}
};
// src/abi/types/StdStringType.ts
var StdStringType = class _StdStringType extends AType {
static {
__name(this, "StdStringType");
}
static swayType = "struct String";
name = "stdString";
static MATCH_REGEX = /^struct (std::string::)?String/m;
static isSuitableFor(params) {
return _StdStringType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
const capitalizedName = "StdString";
this.attributes = {
inputLabel: capitalizedName,
outputLabel: capitalizedName
};
this.requiredFuelsMembersImports = [capitalizedName];
return this.attributes;
}
};
// src/abi/types/StrSliceType.ts
var StrSliceType = class _StrSliceType extends AType {
static {
__name(this, "StrSliceType");
}
static swayType = "str";
name = "strSlice";
static MATCH_REGEX = /^str$/m;
static isSuitableFor(params) {
return _StrSliceType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
const capitalizedName = "StrSlice";
this.attributes = {
inputLabel: capitalizedName,
outputLabel: capitalizedName
};
this.requiredFuelsMembersImports = [capitalizedName];
return this.attributes;
}
};
// src/abi/types/StructType.ts
var StructType = class _StructType extends AType {
static {
__name(this, "StructType");
}
static swayType = "struct MyStruct";
name = "struct";
static MATCH_REGEX = /^struct (.+::)?(.+)$/m;
static IGNORE_REGEX = /^struct (std::.*)?(Vec|RawVec|EvmAddress|Bytes|String|RawBytes)$/m;
static isSuitableFor(params) {
const isAMatch = _StructType.MATCH_REGEX.test(params.type);
const shouldBeIgnored = _StructType.IGNORE_REGEX.test(params.type);
return isAMatch && !shouldBeIgnored;
}
parseComponentsAttributes(_params) {
const structName = this.getStructName();
this.attributes = {
structName,
inputLabel: `${structName}Input`,
outputLabel: `${structName}Output`
};
return this.attributes;
}
getStructName() {
const name = extractStructName({
rawAbiType: this.rawAbiType,
regex: _StructType.MATCH_REGEX
});
return name;
}
getStructContents(params) {
const { types, target } = params;
const { components } = this.rawAbiType;
const structComponents = components;
const members = structComponents.map((component) => {
const { name, type: typeId, typeArguments } = component;
const type = findType({ types, typeId });
let typeDecl;
if (typeArguments) {
typeDecl = parseTypeArguments({
types,
target,
parentTypeId: typeId,
typeArguments
});
} else {
const attributeKey = `${target}Label`;
typeDecl = type.attributes[attributeKey];
}
return `${name}: ${typeDecl}`;
});
return members.join(", ");
}
getStructDeclaration(params) {
const { types } = params;
const { typeParameters } = this.rawAbiType;
if (typeParameters) {
const structs = typeParameters.map((typeId) => findType({ types, typeId }));
const labels = structs.map(({ attributes: { inputLabel } }) => inputLabel);
return `<${labels.join(", ")}>`;
}
return "";
}
};
// src/abi/types/TupleType.ts
var TupleType = class _TupleType extends AType {
static {
__name(this, "TupleType");
}
// Note: a tuple can have more/less than 3x items (like the one bellow)
static swayType = "(_, _, _)";
name = "tupple";
static MATCH_REGEX = /^\([_,\s]+\)$/m;
static isSuitableFor(params) {
return _TupleType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(params) {
const { types } = params;
const inputs = [];
const outputs = [];
this.rawAbiType.components?.forEach((component) => {
const { type: typeId, typeArguments } = component;
if (!typeArguments) {
const { attributes } = findType({ types, typeId });
inputs.push(attributes.inputLabel);
outputs.push(attributes.outputLabel);
} else {
const inputLabel = parseTypeArguments({
types,
typeArguments,
parentTypeId: typeId,
target: "input" /* INPUT */
});
const outputLabel = parseTypeArguments({
types,
typeArguments,
parentTypeId: typeId,
target: "output" /* OUTPUT */
});
inputs.push(inputLabel);
outputs.push(outputLabel);
}
});
this.attributes = {
inputLabel: `[${inputs.join(", ")}]`,
outputLabel: `[${outputs.join(", ")}]`
};
return this.attributes;
}
};
// src/abi/types/U16Type.ts
var U16Type = class _U16Type extends U8Type {
static {
__name(this, "U16Type");
}
static swayType = "u16";
name = "u16";
static MATCH_REGEX = /^u16$/m;
static isSuitableFor(params) {
return _U16Type.MATCH_REGEX.test(params.type);
}
};
// src/abi/types/U256Type.ts
var U256Type = class _U256Type extends U64Type {
static {
__name(this, "U256Type");
}
static swayType = "u256";
name = "u256";
static MATCH_REGEX = /^u256$/m;
static isSuitableFor(params) {
return _U256Type.MATCH_REGEX.test(params.type);
}
};
// src/abi/types/U32Type.ts
var U32Type = class _U32Type extends U8Type {
static {
__name(this, "U32Type");
}
static swayType = "u32";
name = "u32";
static MATCH_REGEX = /^u32$/m;
static isSuitableFor(params) {
return _U32Type.MATCH_REGEX.test(params.type);
}
};
// src/abi/types/VectorType.ts
var VectorType = class _VectorType extends ArrayType {
static {
__name(this, "VectorType");
}
static swayType = "struct Vec";
name = "vector";
static MATCH_REGEX = /^struct (std::vec::)?Vec/m;
static IGNORE_REGEX = /^struct (std::vec::)?RawVec$/m;
static isSuitableFor(params) {
const isAMatch = _VectorType.MATCH_REGEX.test(params.type);
const shouldBeIgnored = _VectorType.IGNORE_REGEX.test(params.type);
return isAMatch && !shouldBeIgnored;
}
parseComponentsAttributes(_params) {
this.attributes = {
inputLabel: `Vec`,
outputLabel: `Vec`
};
return this.attributes;
}
};
// src/utils/supportedTypes.ts
var supportedTypes = [
EmptyType,
ArrayType,
B256Type,
B512Type,
BoolType,
BytesType,
EnumType,
GenericType,
OptionType,
RawUntypedPtr,
RawUntypedSlice,
StdStringType,
StrType,
StrSliceType,
StructType,
TupleType,
U16Type,
U32Type,
U64Type,
U256Type,
U8Type,
VectorType,
EvmAddressType,
ResultType
];
// src/utils/makeType.ts
function makeType(params) {
const { rawAbiType } = params;
const { type } = rawAbiType;
const TypeClass = supportedTypes.find((tc) => tc.isSuitableFor({ type }));
if (!TypeClass) {
throw new FuelError3(ErrorCode4.TYPE_NOT_SUPPORTED, `Type not supported: ${type}`);
}
return new TypeClass(params);
}
__name(makeType, "makeType");
// src/utils/shouldSkipAbiType.ts
function shouldSkipAbiType(params) {
const ignoreList = [
"struct RawVec",
"struct std::vec::RawVec",
"struct RawBytes",
"struct std::bytes::RawBytes"
];
const shouldSkip = ignoreList.indexOf(params.type) >= 0;
return shouldSkip;
}
__name(shouldSkipAbiType, "shouldSkipAbiType");
// src/utils/parseTypes.ts
function parseTypes(params) {
const types = [];
params.rawAbiTypes.forEach((rawAbiType) => {
const { type } = rawAbiType;
const skip = shouldSkipAbiType({ type });
if (!skip) {
const parsedType = makeType({ rawAbiType });
types.push(parsedType);
}
});
types.forEach((type) => {
type.parseComponentsAttributes({ types });
});
return types;
}
__name(parseTypes, "parseTypes");
// src/utils/transpile-abi.ts
var findTypeByConcreteId = /* @__PURE__ */ __name((types, id) => types.find((x) => x.concreteTypeId === id), "findTypeByConcreteId");
var findConcreteTypeById = /* @__PURE__ */ __name((abi, id) => abi.concreteTypes.find((x) => x.concreteTypeId === id), "findConcreteTypeById");
function finsertTypeIdByConcreteTypeId(abi, types, id) {
const concreteType = findConcreteTypeById(abi, id);
if (concreteType.metadataTypeId !== void 0) {
return concreteType.metadataTypeId;
}
const type = findTypeByConcreteId(types, id);
if (type) {
return type.typeId;
}
types.push({
typeId: types.length,
type: concreteType.type,
components: parseComponents(concreteType.components),
concreteTypeId: id,
typeParameters: concreteType.typeParameters ?? null,
originalConcreteTypeId: concreteType?.concreteTypeId
});
return types.length - 1;
}
__name(finsertTypeIdByConcreteTypeId, "finsertTypeIdByConcreteTypeId");
function parseFunctionTypeArguments(abi, types, concreteType) {
return concreteType.typeArguments?.map((cTypeId) => {
const self = findConcreteTypeById(abi, cTypeId);
const type = !isNaN(cTypeId) ? cTypeId : finsertTypeIdByConcreteTypeId(abi, types, cTypeId);
return {
name: "",
type,
// originalTypeId: cTypeId,
typeArguments: parseFunctionTypeArguments(abi, types, self)
};
}) ?? null;
}
__name(parseFunctionTypeArguments, "parseFunctionTypeArguments");
function parseConcreteType(abi, types, concreteTypeId, name) {
const type = finsertTypeIdByConcreteTypeId(abi, types, concreteTypeId);
const concrete = findConcreteTypeById(abi, concreteTypeId);
return {
name: name ?? "",
type,
// concreteTypeId,
typeArguments: parseFunctionTypeArguments(abi, types, concrete)
};
}
__name(parseConcreteType, "parseConcreteType");
function parseComponents(abi, types, components) {
return components?.map((component) => {
const { typeId, name, typeArguments } = component;
const type = !isNaN(typeId) ? typeId : finsertTypeIdByConcreteTypeId(abi, types, typeId);
return {
name,
type,
// originalTypeId: typeId,
typeArguments: parseComponents(abi, types, typeArguments)
};
}) ?? null;
}
__name(parseComponents, "parseComponents");
function transpileAbi(abi) {
if (!abi.specVersion) {
return abi;
}
const types = [];
abi.metadataTypes.forEach((m) => {
const t = {
typeId: m.metadataTypeId,
type: m.type,
components: m.components ?? (m.type === "()" ? [] : null),
typeParameters: m.typeParameters ?? null
};
types.push(t);
});
types.forEach((t) => {
t.components = parseComponents(abi, types, t.components);
});
const functions = abi.functions.map((fn) => {
const inputs = fn.inputs.map(
({ concreteTypeId, name }) => parseConcreteType(abi, types, concreteTypeId, name)
);
const output = parseConcreteType(abi, types, fn.output, "");
return { ...fn, inputs, output };
});
const configurables = abi.configurables.map((conf) => ({
name: conf.name,
configurableType: parseConcreteType(abi, types, conf.concreteTypeId),
offset: conf.offset
}));
const loggedTypes = abi.loggedTypes.map((log) => ({
logId: log.logId,
loggedType: parseConcreteType(abi, types, log.concreteTypeId)
}));
const transpiled = {
encoding: abi.encodingVersion,
types,
functions,
loggedTypes,
messagesTypes: abi.messagesTypes,
configurables,
errorCodes: abi.errorCodes
};
return transpiled;
}
__name(transpileAbi, "transpileAbi");
// src/abi/configurable/Configurable.ts
var Configurable = class {
static {
__name(this, "Configurable");
}
name;
inputLabel;
constructor(params) {
const {
types,
rawAbiConfigurable: {
name,
configurableType: { type, typeArguments }
}
} = params;
this.name = name;
this.inputLabel = resolveInputLabel(types, type, typeArguments);
}
};
// src/abi/Abi.ts
var Abi = class {
static {
__name(this, "Abi");
}
capitalizedName;
camelizedName;
programType;
filepath;
outputDir;
commonTypesInUse = [];
rawContents;
hexlifiedBinContents;
storageSlotsContents;
types;
functions;
configurables;
errorCodes;
constructor(params) {
const {
filepath,
outputDir,
rawContents,
hexlifiedBinContents,
programType,
storageSlotsContents
} = params;
const abiNameRegex = /([^/]+)-abi\.json$/m;
const abiName = filepath.match(abiNameRegex);
const couldNotParseName = !abiName || abiName.length === 0;
if (couldNotParseName) {
throw new FuelError4(
ErrorCode5.PARSE_FAILED,
`Could not parse name from ABI file: ${filepath}.`
);
}
this.programType = programType;
this.capitalizedName = `${normalizeString(abiName[1])}`;
this.camelizedName = this.capitalizedName.replace(/^./m, (x) => x.toLowerCase());
this.filepath = filepath;
this.rawContents = rawContents;
this.hexlifiedBinContents = hexlifiedBinContents;
this.storageSlotsContents = storageSlotsContents;
this.outputDir = outputDir;
const { types, functions, configurables, errorCodes } = this.parse();
this.types = types;
this.functions = functions;
this.configurables = configurables;
this.errorCodes = errorCodes;
this.computeCommonTypesInUse();
}
parse() {
const transpiled = transpileAbi(this.rawContents);
const {
types: rawAbiTypes,
functions: rawAbiFunctions,
configurables: rawAbiConfigurables,
errorCodes: rawErrorCodes
} = transpiled;
const types = parseTypes({ rawAbiTypes });
const functions = parseFunctions({ rawAbiFunctions, types });
const configurables = rawAbiConfigurables.map(
(rawAbiConfigurable) => new Configurable({ types, rawAbiConfigurable })
);
const errorCodes = parseErrorCodes({ rawErrorCodes, types });
return {
types,
functions,
configurables,
errorCodes
};
}
computeCommonTypesInUse() {
const customTypesTable = {
option: "Option",
enum: "Enum",
vector: "Vec",
result: "Result"
};
this.commonTypesInUse = [];
Object.keys(customTypesTable).forEach((typeName) => {
const isInUse = !!this.types.find((t) => t.name === typeName);
if (isInUse) {
const commonTypeLabel = customTypesTable[typeName];
this.commonTypesInUse.push(commonTypeLabel);
}
});
}
};
// src/types/enums/ProgramTypeEnum.ts
var ProgramTypeEnum = /* @__PURE__ */ ((ProgramTypeEnum2) => {
ProgramTypeEnum2["CONTRACT"] = "contract";
ProgramTypeEnum2["SCRIPT"] = "script";
ProgramTypeEnum2["PREDICATE"] = "predicate";
return ProgramTypeEnum2;
})(ProgramTypeEnum || {});
// src/utils/assembleContracts.ts
import { join } from "path";
// src/templates/renderHbsTemplate.ts
import Handlebars from "handlebars";
// src/templates/common/_header.hbs
var header_default = "/* Autogenerated file. Do not edit manually. */\n\n/* eslint-disable max-classes-per-file */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/consistent-type-imports */\n\n\n/*\n Fuels version: {{FUELS}}\n{{#if FORC}}\n Forc version: {{FORC}}\n{{/if}}\n{{#if FUEL_CORE}}\n Fuel-Core version: {{FUEL_CORE}}\n{{/if}}\n*/\n";
// src/templates/renderHbsTemplate.ts
function renderHbsTemplate(params) {
const { data, template, versions } = params;
const options = {
strict: true,
noEscape: true
};
const renderTemplate = Handlebars.compile(template, options);
const renderHeaderTemplate = Handlebars.compile(header_default, options);
const text = renderTemplate({
...data,
header: renderHeaderTemplate(versions)
});
return text.replace(/[\n]{3,}/gm, "\n\n");
}
__name(renderHbsTemplate, "renderHbsTemplate");
// src/templates/common/common.hbs
var common_default = "{{header}}\n\n/**\n * Mimics Sway Enum.\n * Requires one and only one Key-Value pair and raises error if more are provided.\n */\nexport type Enum<T> = {\n [K in keyof T]: Pick<T, K> & { [P in Exclude<keyof T, K>]?: never };\n}[keyof T];\n\n/**\n * Mimics Sway Option and Vectors.\n * Vectors are treated like arrays in Typescript.\n */\nexport type Option<T> = T | undefined;\n\nexport type Vec<T> = T[];\n\n/**\n * Mimics Sway Result enum type.\n * Ok represents the success case, while Err represents the error case.\n */\nexport type Result<T, E> = Enum<{Ok: T, Err: E}>;\n";
// src/templates/common/common.ts
function renderCommonTemplate(params) {
const { versions } = params;
const text = renderHbsTemplate({ template: common_default, versions });
return text;
}
__name(renderCommonTemplate, "renderCommonTemplate");
// src/templates/common/index.hbs
var common_default2 = "{{header}}\n\n{{#each members}}\nexport { {{this}} } from './{{this}}';\n{{/each}}\n";
// src/templates/common/index.ts
function renderIndexTemplate(params) {
const { files, versions } = params;
const members = files.map((f) => f.path.match(/([^/]+)\.ts$/m)?.[1]);
const text = renderHbsTemplate({
template: common_default2,
versions,
data: {
members
}
});
return text;
}
__name(renderIndexTemplate, "renderIndexTemplate");
// src/templates/contract/factory.ts
import { compressBytecode } from "@fuel-ts/utils";
// src/templates/contract/factory.hbs
var factory_default = '{{header}}\n\nimport { ContractFactory as __ContractFactory, decompressBytecode } from "fuels";\nimport type { Provider, Account, DeployContractOptions } from "fuels";\n\nimport { {{capitalizedName}} } from "./{{capitalizedName}}";\n\nconst bytecode = decompressBytecode("{{compressedBytecode}}");\n\nexport class {{capitalizedName}}Factory extends __ContractFactory<{{capitalizedName}}> {\n\n static readonly bytecode = bytecode;\n\n constructor(accountOrProvider: Account | Provider) {\n super(\n bytecode,\n {{capitalizedName}}.abi,\n accountOrProvider,\n {{capitalizedName}}.storageSlots\n );\n }\n\n static deploy (\n wallet: Account,\n options: DeployContractOptions = {}\n ) {\n const factory = new {{capitalizedName}}Factory(wallet);\n return factory.deploy(options);\n }\n}\n';
// src/templates/contract/factory.ts
function renderFactoryTemplate(params) {
const { versions, abi } = params;
const {
camelizedName,
capitalizedName,
rawContents,
storageSlotsContents,
hexlifiedBinContents: hexlifiedBinString
} = abi;
const abiJsonString = JSON.stringify(rawContents, null, 2);
const storageSlotsJsonString = storageSlotsContents ?? "[]";
const text = renderHbsTemplate({
template: factory_default,
versions,
data: {
camelizedName,
capitalizedName,
abiJsonString,
storageSlotsJsonString,
compressedBytecode: compressBytecode(hexlifiedBinString)
}
});
return text;
}
__name(renderFactoryTemplate, "renderFactoryTemplate");
// src/templates/utils/formatEnums.ts
function formatEnums(params) {
const { types } = params;
const enums = types.filter((t) => t.name === "enum").map((t) => {
const et = t;
const structName = et.getStructName();
const inputValues = et.getStructContents({ types, target: "input" /* INPUT */ });
const outputValues = et.getStructContents({ types, target: "output" /* OUTPUT */ });
const inputNativeValues = et.getNativeEnum({ types });
const outputNativeValues = et.getNativeEnum({ types });
const typeAnnotations = et.getStructDeclaration({ types });
return {
structName,
inputValues,
outputValues,
recycleRef: inputValues === outputValues,
// reduces duplication
inputNativeValues,
outputNativeValues,
typeAnnotations
};
}).sort((a, b) => a.structName < b.structName ? -1 : 1);
return { enums };
}
__name(formatEnums, "formatEnums");
// src/templates/utils/formatImports.ts
import { uniq } from "ramda";
var caseInsensitiveSort = /* @__PURE__ */ __name((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()), "caseInsensitiveSort");
function formatImports(params) {
const { types, baseMembers = [] } = params;
const members = types.flatMap((t) => t.requiredFuelsMembersImports);
const imports = uniq(baseMembers.concat(members).sort(caseInsensitiveSort));
return {
imports: imports.length ? imports : void 0
};
}
__name(formatImports, "formatImports");
// src/templates/utils/formatStructs.ts
function formatStructs(params) {
const { types } = params;
const structs = types.filter((t) => t.name === "struct").map((t) => {
const st = t;
const structName = st.getStructName();
const inputValues = st.getStructContents({ types, target: "input" /* INPUT */ });
const outputValues = st.getStructContents({ types, target: "output" /* OUTPUT */ });
const typeAnnotations = st.getStructDeclaration({ types });
return {
structName,
typeAnnotations,
inputValues,
outputValues,
recycleRef: inputValues === outputValues
// reduces duplication
};
}).sort((a, b) => a.structName < b.structName ? -1 : 1);
return { structs };
}
__name(formatStructs, "formatStructs");
// src/templates/contract/main.hbs
var main_default = `{{header}}
import { Contract as __Contract, Interface } from "fuels";
{{#if imports}}
import type {
Provider,
Account,
StorageSlot,
Address,
{{#each imports}}
{{this}},
{{/each}}
} from 'fuels';
{{/if}}
{{#if commonTypesInUse}}
import type { {{commonTypesInUse}} } from "./common";
{{/if}}
{{#each enums}}
{{#if inputNativeValues}}
export enum {{structName}}Input { {{inputNativeValues}} };
{{else}}
export type {{structName}}Input{{typeAnnotations}} = Enum<{ {{inputValues}} }>;
{{/if}}
{{#if outputNativeValues}}
export enum {{structName}}Output { {{outputNativeValues}} };
{{else}}
{{#if recycleRef}}
export type {{structName}}Output{{typeAnnotations}} = {{structName}}Input{{typeAnnotations}};
{{else}}
export type {{structName}}Output{{typeAnnotations}} = Enum<{ {{outputValues}} }>;
{{/if}}
{{/if}}
{{/each}}
{{#each structs}}
export type {{structName}}Input{{typeAnnotations}} = { {{inputValues}} };
{{#if recycleRef}}
export type {{structName}}Output{{typeAnnotations}} = {{structName}}Input{{typeAnnotations}};
{{else}}
export type {{structName}}Output{{typeAnnotations}} = { {{outputValues}} };
{{/if}}
{{/each}}
{{#if configurables}}
export type {{capitalizedName}}Configurables = Partial<{
{{#each configurables}}
{{name}}: {{inputLabel}};
{{/each}}
}>;
{{/if}}
const abi = {{abiJsonString}};
const storageSlots: StorageSlot[] = {{storageSlotsJsonString}};
export class {{capitalizedName}}Interface extends Interface {
constructor() {
super(abi);
}
declare functions: {
{{#each functionsFragments}}
{{this}}: FunctionFragment;
{{/each}}
};
}
export class {{capitalizedName}} extends __Contract {
static readonly abi = abi;
static readonly storageSlots = storageSlots;
declare interface: {{capitalizedName}}Interface;
declare functions: {
{{#each functionsTypedefs}}
{{this}};
{{/each}}
};
constructor(
id: string | Address,
accountOrProvider: Account | Provider,
) {
super(id, abi, accountOrProvider);
}
}
`;
// src/templates/contract/main.ts
function renderMainTemplate(params) {
const { versions, abi } = params;
const { camelizedName, capitalizedName, types, functions, commonTypesInUse, configurables } = abi;
const functionsTypedefs = functions.map((f) => f.getDeclaration());
const functionsFragments = functions.map((f) => f.name);
const encoders = functions.map((f) => ({
functionName: f.name,
input: f.attributes.inputs
}));
const decoders = functions.map((f) => ({
functionName: f.name
}));
const { enums } = formatEnums({ types });
const { structs } = formatStructs({ types });
const { imports } = formatImports({
types,
baseMembers: ["FunctionFragment", "InvokeFunction"]
});
const { rawContents, storageSlotsContents } = params.abi;
const abiJsonString = JSON.stringify(rawContents, null, 2);
const storageSlotsJsonString = storageSlotsContents ?? "[]";
const text = renderHbsTemplate({
template: main_default,
versions,
data: {
camelizedName,
capitalizedName,
commonTypesInUse: commonTypesInUse.join(", "),
functionsTypedefs,
functionsFragments,
encoders,
decoders,
structs,
enums,
imports,
abiJsonString,
storageSlotsJsonString,
configurables
}
});
return text;
}
__name(renderMainTemplate, "renderMainTemplate");
// src/utils/assembleContracts.ts
function assembleContracts(params) {
const { abis, outputDir, versions } = params;
const files = [];
const usesCommonTypes = abis.find((a) => a.commonTypesInUse.length > 0);
abis.forEach((abi) => {
const { capitalizedName } = abi;
const mainFilepath = `${outputDir}/${capitalizedName}.ts`;
const factoryFilepath = `${outputDir}/${capitalizedName}Factory.ts`;
const main = {
path: mainFilepath,
contents: renderMainTemplate({ abi, versions })
};
const factory = {
path: factoryFilepath,
contents: renderFactoryTemplate({ abi, versions })
};
files.push(main);
files.push(factory);
});
const indexFile = {
path: `${outputDir}/index.ts`,
contents: renderIndexTemplate({ files, versions })
};
files.push(indexFile);
if (usesCommonTypes) {
const commonsFilepath = join(outputDir, "common.ts");
const file = {
path: commonsFilepath,
contents: renderCommonTemplate({ versions })
};
files.push(file);
}
return files;
}
__name(assembleContracts, "assembleContracts");
// src/utils/assemblePredicates.ts
import { join as join2 } from "path";
// src/templates/predicate/main.ts
import { ErrorCode as ErrorCode6, FuelError as FuelError5 } from "@fuel-ts/errors";
import { compressBytecode as compressBytecode2 } from "@fuel-ts/utils";
// src/templates/predicate/main.hbs
var main_default2 = `{{header}}
{{#if imports}}
import {
{{#each imports}}
{{this}},
{{/each}}
} from 'fuels';
{{/if}}
{{#if commonTypesInUse}}
import type { {{commonTypesInUse}} } from "./common";
{{/if}}
{{#each enums}}
{{#if inputNativeValues}}
export enum {{structName}}Input { {{inputNativeValues}} };
{{else}}
export type {{structName}}Input{{typeAnnotations}} = Enum<{ {{inputValues}} }>;
{{/if}}
{{#if outputNativeValues}}
export enum {{structName}}Output { {{outputNativeValues}} };
{{else}}
{{#if recycleRef}}
export type {{structName}}Output{{typeAnnotations}} = {{structName}}Input{{typeAnnotations}};
{{else}}
export type {{structName}}Output{{typeAnnotations}} = Enum<{ {{outputValues}} }>;
{{/if}}
{{/if}}
{{/each}}
{{#each structs}}
export type {{structName}}Input{{typeAnnotations}} = { {{inputValues}} };
{{#if recycleRef}}
export type {{structName}}Output{{typeAnnotations}} = {{structName}}Input{{typeAnnotations}};
{{else}}
export type {{structName}}Output{{typeAnnotations}} = { {{outputValues}} };
{{/if}}
{{/each}}
{{#if configurables}}
export type {{capitalizedName}}Configurables = Partial<{
{{#each configurables}}
{{name}}: {{inputLabel}};
{{/each}}
}>;
{{else}}
export type {{capitalizedName}}Configurables = undefined;
{{/if}}
export type {{capitalizedName}}Inputs = [{{inputs}}];
export type {{capitalizedName}}Parameters = Omit<
PredicateParams<{{capitalizedName}}Inputs, {{capitalizedName}}Configurables>,
'abi' | 'bytecode'
>;
const abi = {{abiJsonString}};
const bytecode = decompressBytecode('{{compressedBytecode}}');
export class {{capitalizedName}} extends __Predicate<
{{capitalizedName}}Inputs,
{{capitalizedName}}Configurables
> {
static readonly abi = abi;
static readonly bytecode = bytecode;
constructor(params: {{capitalizedName}}Parameters) {
super({ abi, bytecode, ...params });
}
}
`;
// src/templates/predicate/main.ts
function renderMainTemplate2(params) {
const { abi, versions } = params;
const { types, configurables } = abi;
const {
rawContents,
capitalizedName,
hexlifiedBinContents: hexlifiedBinString,
commonTypesInUse
} = params.abi;
const abiJsonString = JSON.stringify(rawContents, null, 2);
const func = abi.functions.find((f) => f.name === "main");
if (!func) {
throw new FuelError5(ErrorCode6.ABI_MAIN_METHOD_MISSING, `ABI doesn't have a 'main()' method.`);
}
const { enums } = formatEnums({ types });
const { structs } = formatStructs({ types });
const { imports } = formatImports({
types,
baseMembers: [
"Predicate as __Predicate",
"Provider",
"InputValue",
"PredicateParams",
"decompressBytecode"
]
});
const { prefixedInputs: inputs, output } = func.attributes;
const text = renderHbsTemplate({
template: main_default2,
versions,
data: {
inputs,
output,
structs,
enums,
abiJsonString,
compressedBytecode: compressBytecode2(hexlifiedBinString),
capitalizedName,
imports,
configurables,
commonTypesInUse: commonTypesInUse.join(", ")
}
});
return text;
}
__name(renderMainTemplate2, "renderMainTemplate");
// src/utils/assemblePredicates.ts
function assemblePredicates(params) {
const { abis, outputDir, versions } = params;
const files = [];
const usesCommonTypes = abis.find((a) => a.commonTypesInUse.length > 0);
abis.forEach((abi) => {
const { capitalizedName: name } = abi;
const factoryFilepath = `${outputDir}/${name}.ts`;
const factory = {
path: factoryFilepath,
contents: renderMainTemplate2({ abi, versions })
};
files.push(factory);
});
const indexFile = {
path: `${outputDir}/index.ts`,
contents: renderIndexTemplate({ files, versions })
};
files.push(indexFile);
if (usesCommonTypes) {
const commonsFilepath = join2(outputDir, "common.ts");
const file = {
path: commonsFilepath,
contents: renderCommonTemplate({ versions })
};
files.push(file);
}
return files;
}
__name(assemblePredicates, "assemblePredicates");
// src/utils/assembleScripts.ts
import { join as join3 } from "path";
// src/templates/script/main.ts
import { ErrorCode as ErrorCode7, FuelError as FuelError6 } from "@fuel-ts/errors";
import { compressBytecode as compressBytecode3 } from "@fuel-ts/utils";
// src/templates/script/main.hbs
var main_default3 = `{{header}}
{{#if imports}}
import {
{{#each imports}}
{{this}},
{{/each}}
} from 'fuels';
{{/if}}
{{#if commonTypesInUse}}
import type { {{commonTypesInUse}} } from "./common";
{{/if}}
{{#each enums}}
{{#if inputNativeValues}}
export enum {{structName}}Input { {{inputNativeValues}} };
{{else}}
export type {{structName}}Input{{typeAnnotations}} = Enum<{ {{inputValues}} }>;
{{/if}}
{{#if outputNativeValues}}
export enum {{structName}}Output { {{outputNativeValues}} };
{{else}}
{{#if recycleRef}}
export type {{structName}}Output{{typeAnnotations}} = {{structName}}Input{{typeAnnotations}};
{{else}}
export type {{structName}}Output{{typeAnnotations}} = Enum<{ {{outputValues}} }>;
{{/if}}
{{/if}}
{{/each}}
{{#each structs}}
export type {{structName}}Input{{typeAnnotations}} = { {{inputValues}} };
{{#if recycleRef}}
export type {{structName}}Output{{typeAnnotations}} = {{structName}}Input{{typeAnnotations}};
{{else}}
export type {{structName}}Output{{typeAnnotations}} = { {{outputValues}} };
{{/if}}
{{/each}}
export type {{capitalizedName}}Inputs = [{{inputs}}];
export type {{capitalizedName}}Output = {{output}};
{{#if configurables}}
export type {{capitalizedName}}Configurables = Partial<{
{{#each configurables}}
{{name}}: {{inputLabel}};
{{/each}}
}>;
{{/if}}
const abi = {{abiJsonString}};
const bytecode = decompressBytecode('{{compressedBytecode}}');
export class {{capitalizedName}} extends __Script<{{capitalizedName}}Inputs, {{capitalizedName}}Output> {
static readonly abi