@fuel-ts/abi-typegen
Version:
Generates Typescript definitions from Sway ABI Json files
1,682 lines (1,554 loc) • 51.6 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
// src/cli.ts
import { versions as versions2 } from "@fuel-ts/versions";
import { Command, Option } from "commander";
// src/runTypegen.ts
import { ErrorCode as ErrorCode9, FuelError as FuelError9 } from "@fuel-ts/errors";
import { readFileSync as readFileSync3, writeFileSync } from "fs";
import { globSync } from "glob";
import mkdirp from "mkdirp";
import { basename } from "path";
import rimraf from "rimraf";
// src/AbiTypeGen.ts
import { ErrorCode as ErrorCode8, FuelError as FuelError8 } from "@fuel-ts/errors";
// src/abi/Abi.ts
import { ErrorCode as ErrorCode4, FuelError as FuelError4 } from "@fuel-ts/errors";
import { normalizeString } from "@fuel-ts/utils";
// src/utils/findType.ts
import { ErrorCode, 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(ErrorCode.TYPE_ID_NOT_FOUND, `Type ID not found: ${typeId}.`);
}
foundType.parseComponentsAttributes({ types });
return foundType;
}
// src/abi/configurable/Configurable.ts
var Configurable = class {
name;
type;
rawAbiConfigurable;
constructor(params) {
const { types, rawAbiConfigurable } = params;
this.name = rawAbiConfigurable.name;
this.rawAbiConfigurable = rawAbiConfigurable;
this.type = findType({ types, typeId: rawAbiConfigurable.configurableType.type });
}
};
// src/utils/makeConfigurable.ts
function makeConfigurable(params) {
const { types, rawAbiConfigurable } = params;
return new Configurable({ types, rawAbiConfigurable });
}
// src/utils/parseConfigurables.ts
function parseConfigurables(params) {
const { types, rawAbiConfigurables } = params;
const configurables = rawAbiConfigurables.map(
(rawAbiConfigurable) => makeConfigurable({ types, rawAbiConfigurable })
);
return configurables;
}
// 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) => {
let currentLabel;
const currentTypeId = typeArgument.type;
try {
const currentType = findType({ types, typeId: currentTypeId });
currentLabel = currentType.attributes[attributeKey];
} catch (_err) {
currentLabel = "void";
}
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;
}
// src/abi/functions/Function.ts
var Function = class {
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 = this.rawAbiFunction.inputs.map((input) => {
const { name, type: typeId, typeArguments } = input;
const type = findType({ types, typeId });
let typeDecl;
if (typeArguments) {
typeDecl = parseTypeArguments({
types,
target: "input" /* INPUT */,
parentTypeId: typeId,
typeArguments
});
} else {
typeDecl = type.attributes.inputLabel;
}
if (shouldPrefixParams) {
return `${name}: ${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 });
}
// src/utils/parseFunctions.ts
function parseFunctions(params) {
const { types, rawAbiFunctions } = params;
const functions = rawAbiFunctions.map(
(rawAbiFunction) => makeFunction({ types, rawAbiFunction })
);
return functions;
}
// src/utils/makeType.ts
import { ErrorCode as ErrorCode3, FuelError as FuelError3 } from "@fuel-ts/errors";
// src/abi/types/AType.ts
var AType = class {
rawAbiType;
attributes;
requiredFuelsMembersImports;
constructor(params) {
this.rawAbiType = params.rawAbiType;
this.attributes = {
inputLabel: "unknown",
outputLabel: "unknown"
};
this.requiredFuelsMembersImports = [];
}
};
// src/abi/types/ArrayType.ts
var _ArrayType = class extends AType {
name = "array";
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;
}
};
var ArrayType = _ArrayType;
// Note: the array length expressed in '; 2]' could be any length
__publicField(ArrayType, "swayType", "[_; 2]");
__publicField(ArrayType, "MATCH_REGEX", /^\[_; ([0-9]+)\]$/m);
// src/abi/types/StrType.ts
var _StrType = class extends AType {
name = "str";
static isSuitableFor(params) {
return _StrType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
this.attributes = {
inputLabel: "string",
outputLabel: "string"
};
return this.attributes;
}
};
var StrType = _StrType;
// Note: the str length expressed in '[3]' could be any length
__publicField(StrType, "swayType", "str[3]");
__publicField(StrType, "MATCH_REGEX", /^str\[(.+)\]$/m);
// src/abi/types/B256Type.ts
var _B256Type = class extends StrType {
name = "b256";
static isSuitableFor(params) {
return _B256Type.MATCH_REGEX.test(params.type);
}
};
var B256Type = _B256Type;
__publicField(B256Type, "swayType", "b256");
__publicField(B256Type, "MATCH_REGEX", /^b256$/m);
// src/abi/types/B512Type.ts
var _B512Type = class extends B256Type {
name = "b512";
static isSuitableFor(params) {
return _B512Type.MATCH_REGEX.test(params.type);
}
};
var B512Type = _B512Type;
__publicField(B512Type, "swayType", "struct B512");
__publicField(B512Type, "MATCH_REGEX", /^struct B512$/m);
// src/abi/types/BoolType.ts
var _BoolType = class extends AType {
name = "bool";
static isSuitableFor(params) {
return _BoolType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
this.attributes = {
inputLabel: "boolean",
outputLabel: "boolean"
};
return this.attributes;
}
};
var BoolType = _BoolType;
__publicField(BoolType, "swayType", "bool");
__publicField(BoolType, "MATCH_REGEX", /^bool$/m);
// src/abi/types/BytesType.ts
var _BytesType = class extends ArrayType {
name = "bytes";
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;
}
};
var BytesType = _BytesType;
__publicField(BytesType, "swayType", "struct Bytes");
__publicField(BytesType, "MATCH_REGEX", /^struct Bytes/m);
// src/utils/extractStructName.ts
import { ErrorCode as ErrorCode2, FuelError as FuelError2 } from "@fuel-ts/errors";
function extractStructName(params) {
const { rawAbiType, regex } = params;
const match = rawAbiType.type.match(params.regex)?.[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(ErrorCode2.JSON_ABI_ERROR, errorMessage);
}
return match;
}
// src/abi/types/EnumType.ts
var _EnumType = class extends AType {
name = "enum";
static isSuitableFor(params) {
const isAMatch = _EnumType.MATCH_REGEX.test(params.type);
const shouldBeIgnored = _EnumType.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: _EnumType.MATCH_REGEX
});
return name;
}
getNativeEnum(params) {
const { types } = params;
const typeHash = types.reduce(
(hash, row) => ({
...hash,
[row.rawAbiType.typeId]: row
}),
{}
);
const { components } = this.rawAbiType;
const enumComponents = components;
if (!enumComponents.every(({ type }) => !typeHash[type])) {
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 } = component;
if (typeId === 0) {
return `${name}: []`;
}
const { attributes } = findType({ types, typeId });
return `${name}: ${attributes[attributeKey]}`;
});
return contents.join(", ");
}
};
var EnumType = _EnumType;
__publicField(EnumType, "swayType", "enum MyEnumName");
__publicField(EnumType, "MATCH_REGEX", /^enum (.+)$/m);
__publicField(EnumType, "IGNORE_REGEX", /^enum Option$/m);
// src/abi/types/EvmAddressType.ts
var _EvmAddressType = class extends AType {
name = "evmAddress";
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;
}
};
var EvmAddressType = _EvmAddressType;
__publicField(EvmAddressType, "swayType", "struct EvmAddress");
__publicField(EvmAddressType, "MATCH_REGEX", /^struct EvmAddress$/m);
// src/abi/types/GenericType.ts
var _GenericType = class extends AType {
name = "generic";
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;
}
};
var GenericType = _GenericType;
__publicField(GenericType, "swayType", "generic T");
__publicField(GenericType, "MATCH_REGEX", /^generic ([^\s]+)$/m);
// src/abi/types/OptionType.ts
var _OptionType = class extends AType {
name = "option";
static isSuitableFor(params) {
return _OptionType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
this.attributes = {
inputLabel: `Option`,
outputLabel: `Option`
};
return this.attributes;
}
};
var OptionType = _OptionType;
__publicField(OptionType, "swayType", "enum Option");
__publicField(OptionType, "MATCH_REGEX", /^enum Option$/m);
// src/abi/types/U8Type.ts
var _U8Type = class extends AType {
name = "u8";
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;
}
};
var U8Type = _U8Type;
__publicField(U8Type, "swayType", "u8");
__publicField(U8Type, "MATCH_REGEX", /^u8$/m);
// src/abi/types/U64Type.ts
var _U64Type = class extends U8Type {
name = "u64";
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);
}
};
var U64Type = _U64Type;
__publicField(U64Type, "swayType", "u64");
__publicField(U64Type, "MATCH_REGEX", /^u64$/m);
// src/abi/types/RawUntypedPtr.ts
var _RawUntypedPtr = class extends U64Type {
name = "rawUntypedPtr";
static isSuitableFor(params) {
return _RawUntypedPtr.MATCH_REGEX.test(params.type);
}
};
var RawUntypedPtr = _RawUntypedPtr;
__publicField(RawUntypedPtr, "swayType", "raw untyped ptr");
__publicField(RawUntypedPtr, "MATCH_REGEX", /^raw untyped ptr$/m);
// src/abi/types/RawUntypedSlice.ts
var _RawUntypedSlice = class extends ArrayType {
name = "rawUntypedSlice";
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;
}
};
var RawUntypedSlice = _RawUntypedSlice;
__publicField(RawUntypedSlice, "swayType", "raw untyped slice");
__publicField(RawUntypedSlice, "MATCH_REGEX", /^raw untyped slice$/m);
// src/abi/types/StdStringType.ts
var _StdStringType = class extends AType {
name = "stdString";
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;
}
};
var StdStringType = _StdStringType;
__publicField(StdStringType, "swayType", "struct String");
__publicField(StdStringType, "MATCH_REGEX", /^struct String/m);
// src/abi/types/StrSliceType.ts
var _StrSliceType = class extends AType {
name = "strSlice";
static isSuitableFor(params) {
return _StrSliceType.MATCH_REGEX.test(params.type);
}
parseComponentsAttributes(_params) {
this.attributes = {
inputLabel: "StrSlice",
outputLabel: "StrSlice"
};
return this.attributes;
}
};
var StrSliceType = _StrSliceType;
__publicField(StrSliceType, "swayType", "str");
__publicField(StrSliceType, "MATCH_REGEX", /^str$/m);
// src/abi/types/StructType.ts
var _StructType = class extends AType {
name = "struct";
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 "";
}
};
var StructType = _StructType;
__publicField(StructType, "swayType", "struct MyStruct");
__publicField(StructType, "MATCH_REGEX", /^struct (.+)$/m);
__publicField(StructType, "IGNORE_REGEX", /^struct (Vec|RawVec|EvmAddress|Bytes|String)$/m);
// src/abi/types/TupleType.ts
var _TupleType = class extends AType {
name = "tupple";
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;
}
};
var TupleType = _TupleType;
// Note: a tuple can have more/less than 3x items (like the one bellow)
__publicField(TupleType, "swayType", "(_, _, _)");
__publicField(TupleType, "MATCH_REGEX", /^\([_,\s]+\)$/m);
// src/abi/types/U16Type.ts
var _U16Type = class extends U8Type {
name = "u16";
static isSuitableFor(params) {
return _U16Type.MATCH_REGEX.test(params.type);
}
};
var U16Type = _U16Type;
__publicField(U16Type, "swayType", "u16");
__publicField(U16Type, "MATCH_REGEX", /^u16$/m);
// src/abi/types/U256Type.ts
var _U256Type = class extends U64Type {
name = "u256";
static isSuitableFor(params) {
return _U256Type.MATCH_REGEX.test(params.type);
}
};
var U256Type = _U256Type;
__publicField(U256Type, "swayType", "u256");
__publicField(U256Type, "MATCH_REGEX", /^u256$/m);
// src/abi/types/U32Type.ts
var _U32Type = class extends U8Type {
name = "u32";
static isSuitableFor(params) {
return _U32Type.MATCH_REGEX.test(params.type);
}
};
var U32Type = _U32Type;
__publicField(U32Type, "swayType", "u32");
__publicField(U32Type, "MATCH_REGEX", /^u32$/m);
// src/abi/types/VectorType.ts
var _VectorType = class extends ArrayType {
name = "vector";
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;
}
};
var VectorType = _VectorType;
__publicField(VectorType, "swayType", "struct Vec");
__publicField(VectorType, "MATCH_REGEX", /^struct Vec/m);
__publicField(VectorType, "IGNORE_REGEX", /^struct RawVec$/m);
// src/utils/supportedTypes.ts
var supportedTypes = [
ArrayType,
B256Type,
B512Type,
BoolType,
BytesType,
EnumType,
GenericType,
OptionType,
RawUntypedPtr,
RawUntypedSlice,
StdStringType,
StrType,
StrSliceType,
StructType,
TupleType,
U16Type,
U32Type,
U64Type,
U256Type,
U8Type,
VectorType,
EvmAddressType
];
// 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(ErrorCode3.TYPE_NOT_SUPPORTED, `Type not supported: ${type}`);
}
return new TypeClass(params);
}
// src/utils/shouldSkipAbiType.ts
function shouldSkipAbiType(params) {
const ignoreList = ["()", "struct RawVec"];
const shouldSkip = ignoreList.indexOf(params.type) >= 0;
return shouldSkip;
}
// 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;
}
// src/abi/Abi.ts
var Abi = class {
name;
programType;
filepath;
outputDir;
commonTypesInUse = [];
rawContents;
hexlifiedBinContents;
storageSlotsContents;
types;
functions;
configurables;
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(
ErrorCode4.PARSE_FAILED,
`Could not parse name from ABI file: ${filepath}.`
);
}
const name = `${normalizeString(abiName[1])}Abi`;
this.name = name;
this.programType = programType;
this.filepath = filepath;
this.rawContents = rawContents;
this.hexlifiedBinContents = hexlifiedBinContents;
this.storageSlotsContents = storageSlotsContents;
this.outputDir = outputDir;
const { types, functions, configurables } = this.parse();
this.types = types;
this.functions = functions;
this.configurables = configurables;
this.computeCommonTypesInUse();
}
parse() {
const {
types: rawAbiTypes,
functions: rawAbiFunctions,
configurables: rawAbiConfigurables
} = this.rawContents;
const types = parseTypes({ rawAbiTypes });
const functions = parseFunctions({ rawAbiFunctions, types });
const configurables = parseConfigurables({ rawAbiConfigurables, types });
return {
types,
functions,
configurables
};
}
computeCommonTypesInUse() {
const customTypesTable = {
option: "Option",
enum: "Enum",
vector: "Vec"
};
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 { versions } from "@fuel-ts/versions";
import { compile } from "handlebars";
// src/templates/common/_header.hbs
var header_default = "/* Autogenerated file. Do not edit manually. */\n\n/* tslint:disable */\n/* eslint-disable */\n\n/*\n Fuels version: {{FUELS}}\n Forc version: {{FORC}}\n Fuel-Core version: {{FUEL_CORE}}\n*/\n";
// src/templates/renderHbsTemplate.ts
function renderHbsTemplate(params) {
const { data, template } = params;
const options = {
strict: true,
noEscape: true
};
const renderTemplate = compile(template, options);
const renderHeaderTemplate = compile(header_default, options);
const text = renderTemplate({
...data,
header: renderHeaderTemplate(versions)
});
return text.replace(/[\n]{3,}/gm, "\n\n");
}
// src/templates/common/common.hbs
var common_default = "{{header}}\n\n/*\n Mimics Sway Enum, requires at least one Key-Value but\n does not raise error on multiple pairs.\n This is done in the abi-coder\n*/\nexport type Enum<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> &\n U[keyof U];\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";
// src/templates/common/common.ts
function renderCommonTemplate() {
const text = renderHbsTemplate({ template: common_default });
return text;
}
// src/templates/common/index.hbs
var common_default2 = "{{header}}\n\n{{#if isGeneratingContracts}}\n{{#each abis}}\nexport type { {{name}} } from './{{name}}';\n{{/each}}\n{{/if}}\n\n{{#each abis}}\nexport { {{name}}__factory } from './factories/{{name}}__factory';\n{{/each}}\n";
// src/templates/common/index.ts
function renderIndexTemplate(params) {
const { abis } = params;
const isGeneratingContracts = abis[0].programType === "contract" /* CONTRACT */;
const text = renderHbsTemplate({
template: common_default2,
data: { abis, isGeneratingContracts }
});
return text;
}
// src/templates/contract/bytecode.hbs
var bytecode_default = "{{header}}\n\nexport default '{{hexlifiedBytecode}}'";
// src/templates/contract/bytecode.ts
function renderBytecodeTemplate(params) {
const text = renderHbsTemplate({
template: bytecode_default,
data: {
hexlifiedBytecode: params.hexlifiedBytecode
}
});
return text;
}
// src/templates/utils/formatConfigurables.ts
function formatConfigurables(params) {
const { configurables } = params;
const formattedConfigurables = configurables.map((c) => {
const {
name,
type: {
attributes: { inputLabel }
}
} = c;
return {
configurableName: name,
configurableType: inputLabel
};
});
return { formattedConfigurables };
}
// 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 });
return {
structName,
inputValues,
outputValues,
recycleRef: inputValues === outputValues,
// reduces duplication
inputNativeValues,
outputNativeValues
};
});
return { enums };
}
// src/templates/utils/formatImports.ts
import { uniq } from "ramda";
var caseInsensitiveSort = (a, b) => a.toLowerCase().localeCompare(b.toLowerCase());
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
};
}
// 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
};
});
return { structs };
}
// src/templates/contract/dts.hbs
var dts_default = `{{header}}
{{#if imports}}
import type {
{{#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 = Enum<{ {{inputValues}} }>;
{{/if}}
{{#if outputNativeValues}}
export enum {{structName}}Output { {{outputNativeValues}} };
{{else}}
{{#if recycleRef}}
export type {{structName}}Output = {{structName}}Input;
{{else}}
export type {{structName}}Output = 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 formattedConfigurables}}
export type {{capitalizedName}}Configurables = {
{{#each formattedConfigurables}}
{{configurableName}}: {{configurableType}};
{{/each}}
};
{{/if}}
interface {{capitalizedName}}Interface extends Interface {
functions: {
{{#each functionsFragments}}
{{this}}: FunctionFragment;
{{/each}}
};
{{#each encoders}}
encodeFunctionData(functionFragment: '{{functionName}}', values: [{{input}}]): Uint8Array;
{{/each}}
{{#each decoders}}
decodeFunctionData(functionFragment: '{{functionName}}', data: BytesLike): DecodedValue;
{{/each}}
}
export class {{capitalizedName}} extends Contract {
interface: {{capitalizedName}}Interface;
functions: {
{{#each functionsTypedefs}}
{{this}};
{{/each}}
};
}
`;
// src/templates/contract/dts.ts
function renderDtsTemplate(params) {
const { name: capitalizedName, types, functions, commonTypesInUse, configurables } = params.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: [
"Interface",
"FunctionFragment",
"DecodedValue",
"Contract",
"BytesLike",
"InvokeFunction"
]
});
const { formattedConfigurables } = formatConfigurables({ configurables });
const text = renderHbsTemplate({
template: dts_default,
data: {
capitalizedName,
commonTypesInUse: commonTypesInUse.join(", "),
functionsTypedefs,
functionsFragments,
encoders,
decoders,
structs,
enums,
imports,
formattedConfigurables
}
});
return text;
}
// src/templates/contract/factory.hbs
var factory_default = '{{header}}\n\nimport { Interface, Contract, ContractFactory } from "fuels";\nimport type { Provider, Account, AbstractAddress, BytesLike, DeployContractOptions, StorageSlot } from "fuels";\nimport type { {{capitalizedName}}, {{capitalizedName}}Interface } from "../{{capitalizedName}}";\n\nconst _abi = {{abiJsonString}};\n\nconst _storageSlots: StorageSlot[] = {{storageSlotsJsonString}};\n\nexport class {{capitalizedName}}__factory {\n static readonly abi = _abi;\n\n static readonly storageSlots = _storageSlots;\n\n static createInterface(): {{capitalizedName}}Interface {\n return new Interface(_abi) as unknown as {{capitalizedName}}Interface\n }\n\n static connect(\n id: string | AbstractAddress,\n accountOrProvider: Account | Provider\n ): {{capitalizedName}} {\n return new Contract(id, _abi, accountOrProvider) as unknown as {{capitalizedName}}\n }\n\n static async deployContract(\n bytecode: BytesLike,\n wallet: Account,\n options: DeployContractOptions = {}\n ): Promise<{{capitalizedName}}> {\n const factory = new ContractFactory(bytecode, _abi, wallet);\n\n const { storageSlots } = {{capitalizedName}}__factory;\n\n const contract = await factory.deployContract({\n storageSlots,\n ...options,\n });\n\n return contract as unknown as {{capitalizedName}};\n }\n}\n';
// src/templates/contract/factory.ts
function renderFactoryTemplate(params) {
const { name: capitalizedName, rawContents, storageSlotsContents } = params.abi;
const abiJsonString = JSON.stringify(rawContents, null, 2);
const storageSlotsJsonString = storageSlotsContents ?? "[]";
const text = renderHbsTemplate({
template: factory_default,
data: { capitalizedName, abiJsonString, storageSlotsJsonString }
});
return text;
}
// src/utils/assembleContracts.ts
function assembleContracts(params) {
const { abis, outputDir } = params;
const files = [];
const usesCommonTypes = abis.find((a) => a.commonTypesInUse.length > 0);
abis.forEach((abi) => {
const { name } = abi;
const dtsFilepath = `${outputDir}/${name}.d.ts`;
const factoryFilepath = `${outputDir}/factories/${name}__factory.ts`;
const hexBinFilePath = `${outputDir}/${name}.hex.ts`;
const dts = {
path: dtsFilepath,
contents: renderDtsTemplate({ abi })
};
const factory = {
path: factoryFilepath,
contents: renderFactoryTemplate({ abi })
};
const hexBinFile = {
path: hexBinFilePath,
contents: renderBytecodeTemplate({
hexlifiedBytecode: abi.hexlifiedBinContents
})
};
files.push(dts);
files.push(factory);
files.push(hexBinFile);
});
const indexFile = {
path: `${outputDir}/index.ts`,
contents: renderIndexTemplate({ abis })
};
files.push(indexFile);
if (usesCommonTypes) {
const commonsFilepath = join(outputDir, "common.d.ts");
const file = {
path: commonsFilepath,
contents: renderCommonTemplate()
};
files.push(file);
}
return files;
}
// src/utils/assemblePredicates.ts
import { join as join2 } from "path";
// src/templates/predicate/factory.ts
import { ErrorCode as ErrorCode5, FuelError as FuelError5 } from "@fuel-ts/errors";
// src/templates/predicate/factory.hbs
var factory_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 = Enum<{ {{inputValues}} }>;
{{/if}}
{{#if outputNativeValues}}
export enum {{structName}}Output { {{outputNativeValues}} };
{{else}}
{{#if recycleRef}}
export type {{structName}}Output = {{structName}}Input;
{{else}}
export type {{structName}}Output = 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}}Configurables = {
{{#each formattedConfigurables}}
{{configurableName}}: {{configurableType}};
{{/each}}
};
type {{capitalizedName}}Inputs = [{{inputs}}];
const _abi = {{abiJsonString}}
const _bin = '{{hexlifiedBinString}}'
export class {{capitalizedName}}__factory {
static readonly abi = _abi
static readonly bin = _bin;
static createInstance(provider: Provider, configurables?: {{capitalizedName}}Configurables) {
const { abi, bin } = {{capitalizedName}}__factory
const predicate = new Predicate(bin, provider, abi, configurables);
return predicate;
}
}
`;
// src/templates/predicate/factory.ts
function renderFactoryTemplate2(params) {
const { abi } = params;
const { types, configurables } = abi;
const {
rawContents,
name: capitalizedName,
hexlifiedBinContents: hexlifiedBinString
} = params.abi;
const abiJsonString = JSON.stringify(rawContents, null, 2);
const func = abi.functions.find((f) => f.name === "main");
if (!func) {
throw new FuelError5(ErrorCode5.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", "Provider"] });
const { formattedConfigurables } = formatConfigurables({ configurables });
const { prefixedInputs: inputs, output } = func.attributes;
const text = renderHbsTemplate({
template: factory_default2,
data: {
inputs,
output,
structs,
enums,
abiJsonString,
hexlifiedBinString,
capitalizedName,
imports,
formattedConfigurables
}
});
return text;
}
// src/utils/assemblePredicates.ts
function assemblePredicates(params) {
const { abis, outputDir } = params;
const files = [];
const usesCommonTypes = abis.find((a) => a.commonTypesInUse.length > 0);
abis.forEach((abi) => {
const { name } = abi;
const factoryFilepath = `${outputDir}/factories/${name}__factory.ts`;
const factory = {
path: factoryFilepath,
contents: renderFactoryTemplate2({ abi })
};
files.push(factory);
});
const indexFile = {
path: `${outputDir}/index.ts`,
contents: renderIndexTemplate({ abis })
};
files.push(indexFile);
if (usesCommonTypes) {
const commonsFilepath = join2(outputDir, "common.d.ts");
const file = {
path: commonsFilepath,
contents: renderCommonTemplate()
};
files.push(file);
}
return files;
}
// src/utils/assembleScripts.ts
import { join as join3 } from "path";
// src/templates/script/factory.ts
import { ErrorCode as ErrorCode6, FuelError as FuelError6 } from "@fuel-ts/errors";
// src/templates/script/factory.hbs
var factory_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 = Enum<{ {{inputValues}} }>;
{{/if}}
{{#if outputNativeValues}}
export enum {{structName}}Output { {{outputNativeValues}} };
{{else}}
{{#if recycleRef}}
export type {{structName}}Output = {{structName}}Input;
{{else}}
export type {{structName}}Output = 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}}
type {{capitalizedName}}Inputs = [{{inputs}}];
type {{capitalizedName}}Output = {{output}};
{{#if formattedConfigurables}}
export type {{capitalizedName}}Configurables = {
{{#each formattedConfigurables}}
{{configurableName}}: {{configurableType}};
{{/each}}
};
{{/if}}
const _abi = {{abiJsonString}}
const _bin = '{{hexlifiedBinString}}'
export class {{capitalizedName}}__factory {
static readonly abi = _abi
static readonly bin = _bin
static createInstance(wallet: Account) {
const { abi, bin } = {{capitalizedName}}__factory
const script = new Script<
{{capitalizedName}}Inputs,
{{capitalizedName}}Output
>(bin, abi, wallet);
return script;
}
}
`;
// src/templates/script/factory.ts
function renderFactoryTemplate3(params) {
const { abi } = params;
const { types, configurables } = abi;
const {
rawContents,
name: capitalizedName,
hexlifiedBinContents: hexlifiedBinString
} = params.abi;
const abiJsonString = JSON.stringify(rawContents, null, 2);
const func = abi.functions.find((f) => f.name === "main");
if (!func) {
throw new FuelError6(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: ["Script", "Account"] });
const { formattedConfigurables } = formatConfigurables({ configurables });
const { prefixedInputs: inputs, output } = func.attributes;
const text = renderHbsTemplate({
template: factory_default3,
data: {
inputs,
output,
structs,
enums,
abiJsonString,
hexlifiedBinString,
capitalizedName,
imports,
formattedConfigurables
}
});
return text;
}
// src/utils/assembleScripts.ts
function assembleScripts(params) {
const { abis, outputDir } = params;
const files = [];
const usesCommonTypes = abis.find((a) => a.commonTypesInUse.length > 0);
abis.forEach((abi) => {
const { name } = abi;
const factoryFilepath = `${outputDir}/factories/${name}__factory.ts`;
const factory = {
path: factoryFilepath,
contents: renderFactoryTemplate3({ abi })
};
files.push(factory);
});
const indexFile = {
path: `${outputDir}/index.ts`,
contents: renderIndexTemplate({ abis })
};
files.push(indexFile);
if (usesCommonTypes) {
const commonsFilepath = join3(outputDir, "common.d.ts");
const file = {
path: commonsFilepath,
contents: renderCommonTemplate()
};
files.push(file);
}
return files;
}
// src/utils/validateBinFile.ts
import { ErrorCode as ErrorCode7, FuelError as FuelError7 } from "@fuel-ts/errors";
var upperFirst = (s) => s[0].toUpperCase() + s.slice(1);
function validateBinFile(params) {
const { abiFilepath, binFilepath, binExists, programType } = params;
const isScript = programType === "script" /* SCRIPT */;
if (!binExists && isScript) {
throw new FuelError7(
ErrorCode7.BIN_FILE_NOT_FOUND,
[
`Could not find BIN file for counterpart ${upperFirst(programType)} ABI.`,
` - ABI: ${abiFilepath}`,
` - BIN: ${binFilepath}`,
programType
].join("\n")
);
}
}
// src/AbiTypeGen.ts
var AbiTypeGen = class {
abis;
abiFiles;
binFiles;
storageSlotsFiles;
outputDir;
files;
constructor(params) {
const { abiFiles, binFiles, outputDir, programType, storageSlotsFiles } = params;
this.outputDir = outputDir;
this.abiFiles = abiFiles;
this.binFiles = binFiles;
this.storageSlotsFiles = storageSlotsFiles;
this.abis = this.abiFiles.map((abiFile) => {
const binFilepath = abiFile.path.replace("-abi.json", ".bin");
const relatedBinFile = this.binFiles.find(({ path }) => path === binFilepath);
const storageSlotFilepath = abiFile.path.replace("-abi.json", "-storage_slots.json");
const relatedStorageSlotsFile = this.storageSlotsFiles.find(
({ path }) => path === storageSlotFilepath
);
if (!relatedBinFile) {
validateBinFile({
abiFilepath: abiFile.path,
binExists: !!relatedBinFile,
binFilepath,
programType
});
}
const abi = new Abi({
filepath: abiFile.path,
rawContents: JSON.parse(abiFile.contents),
hexlifiedBinContents: relatedBinFile?.contents,
storageSlotsContents: relatedStorageSlotsFile?.contents,
outputDir,
programType
});
return abi;
});
this.files = this.getAssembledFiles({ programType });
}
getAssembledFiles(params) {
const { abis, outputDir } = this;
const { programType } = params;
switch (programType) {
case "contract" /* CONTRACT */:
return assembleContracts({ abis, outputDir });
case "script" /* SCRIPT */:
return assembleScripts({ abis, outputDir });
case "predicate" /* PREDICATE */:
return assemblePredicates({ abis, outputDir });
default:
throw new FuelError8(
ErrorCode8.INVALID_INPUT_PARAMETERS,
`Invalid Typegen programType: ${programType}. Must be one of ${Object.values(
ProgramTypeEnum
)}`
);
}
}
};
// src/utils/collectBinFilePaths.ts
import { hexlify } from "@fuel-ts/utils";
import { existsSync, readFileSync } from "fs";
var collectBinFilepaths = (params) => {
const { filepaths, programType } = params;
const binFiles = filepaths.map((abiFilepath) => {
const binFilepath = abiFilepath.replace("-abi.json", ".bin");
const binExists = existsSync(binFilepath);
validateBinFile({ abiFilepath, binFilepath, binExists, programType });
const bin = {
path: binFilepath,
contents: hexlify(readFileSync(binFilepath))
};
return bin;
});
return binFiles;
};
// src/utils/collectStorageSlotsFilePaths.ts
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
var collectStorageSlotsFilepaths = (params) => {
const { filepaths, programType } = params;
const storageSlotsFiles = [];
if (programType !== "contract" /* CONTRACT */) {
return storageSlotsFiles;
}
filepaths.forEach((abiFilepath) => {
const storageSlotsFilepath = abiFilepath.replace("-abi.json", "-storage_slots.json");
const storageSlotsExists = existsSync2(storageSlotsFilepath);
if (storageSlotsExists) {
const storageSlots = {
path: storageSlotsFilepath,
contents: readFileSync2(storageSlotsFilepath, "utf-8")
};
storageSlotsFiles.push(storageSlots);
}
});
return storageSlotsFiles;
};
// src/runTypegen.ts
function runTypegen(params) {
const { cwd, inputs, output, silent, programType, filepaths: inputFilepaths } = params;
const cwdBasename = basename(cwd);
function log(...args) {
if (!silent) {
process.stdout.write(`${args.join(" ")}
`);
}
}
let filepaths = [];
if (!inputFilepaths?.length && inputs?.length) {
filepaths = inputs.flatMap((i) => globSync(i, { cwd }));
} else if (inputFilepaths?.length) {
filepaths = inputFilepaths;
} else {
throw new FuelError9(
ErrorCode9.MISSING_REQUIRED_PARAMETER,
`At least one parameter should be supplied: 'input' or 'filepaths'.`
);
}
const abiFiles = filepaths.map((filepath) => {
const abi = {
path: filepath,
contents: readFileSync3(filepath, "utf-8")
};
return abi;
});
if (!abiFiles.length) {
throw new FuelError9(ErrorCode9.NO_ABIS_FOUND, `no ABI found at '${inputs}'`);
}
const binFiles = collectBinFilepaths({ filepaths, programType });
const storageSlotsFiles = collectStorageSlotsFilepaths({ filepaths, programType });
const abiTypeGen = new AbiTypeGen({
outputDir: output,
abiFiles,
binFiles,
storageSlotsFiles,
programType
});
log("Generating files..\n");
mkdirp.sync(`${output}/factories`);
abiTypeGen.files.forEach((file) => {
rimraf.sync(file.path);
writeFileSync(file.path, file.contents);
const trimPathRegex = new RegExp(`^.+${cwdBasename}/`, "m");
log(` - ${file.path.replace(trimPathRegex, "")}`);
});
log("\nDone.\u26A1");
}
// src/cli.ts
function resolveProgramType(params) {
const { contract, script, predicate } = params;
const noneSpecified = !contract && !script && !predicate;
if (contract || noneSpecified) {
return "contract" /* CONTRACT */;
}
if (predicate) {
return "predicate" /* PREDICATE */;
}
return "script" /* SCRIPT */;
}
function runCliAction(options) {
const { input