UNPKG

@fuel-ts/abi-typegen

Version:

Generates Typescript definitions from Sway ABI Json files

1 lines 92.5 kB
{"version":3,"sources":["../src/cli.ts","../src/runTypegen.ts","../src/AbiTypeGen.ts","../src/abi/Abi.ts","../src/utils/findType.ts","../src/abi/configurable/Configurable.ts","../src/utils/makeConfigurable.ts","../src/utils/parseConfigurables.ts","../src/utils/parseTypeArguments.ts","../src/abi/functions/Function.ts","../src/utils/makeFunction.ts","../src/utils/parseFunctions.ts","../src/utils/makeType.ts","../src/abi/types/AType.ts","../src/abi/types/ArrayType.ts","../src/abi/types/StrType.ts","../src/abi/types/B256Type.ts","../src/abi/types/B512Type.ts","../src/abi/types/BoolType.ts","../src/abi/types/BytesType.ts","../src/utils/extractStructName.ts","../src/abi/types/EnumType.ts","../src/abi/types/EvmAddressType.ts","../src/abi/types/GenericType.ts","../src/abi/types/OptionType.ts","../src/abi/types/U8Type.ts","../src/abi/types/U64Type.ts","../src/abi/types/RawUntypedPtr.ts","../src/abi/types/RawUntypedSlice.ts","../src/abi/types/StdStringType.ts","../src/abi/types/StrSliceType.ts","../src/abi/types/StructType.ts","../src/abi/types/TupleType.ts","../src/abi/types/U16Type.ts","../src/abi/types/U256Type.ts","../src/abi/types/U32Type.ts","../src/abi/types/VectorType.ts","../src/utils/supportedTypes.ts","../src/utils/shouldSkipAbiType.ts","../src/utils/parseTypes.ts","../src/types/enums/ProgramTypeEnum.ts","../src/utils/assembleContracts.ts","../src/templates/renderHbsTemplate.ts","../src/templates/common/common.ts","../src/templates/common/index.ts","../src/templates/contract/bytecode.ts","../src/templates/utils/formatConfigurables.ts","../src/templates/utils/formatEnums.ts","../src/templates/utils/formatImports.ts","../src/templates/utils/formatStructs.ts","../src/templates/contract/dts.ts","../src/templates/contract/factory.ts","../src/utils/assemblePredicates.ts","../src/templates/predicate/factory.ts","../src/utils/assembleScripts.ts","../src/templates/script/factory.ts","../src/utils/validateBinFile.ts","../src/utils/collectBinFilePaths.ts","../src/utils/collectStorageSlotsFilePaths.ts","../src/bin.ts"],"sourcesContent":["import { versions } from '@fuel-ts/versions';\nimport { Command, Option } from 'commander';\n\nimport { runTypegen } from './runTypegen';\nimport { ProgramTypeEnum } from './types/enums/ProgramTypeEnum';\n\nexport interface ICliParams {\n inputs: string[];\n output: string;\n silent?: boolean;\n contract?: boolean;\n script?: boolean;\n predicate?: boolean;\n}\n\nexport function resolveProgramType(params: {\n contract?: boolean;\n script?: boolean;\n predicate?: boolean;\n}) {\n const { contract, script, predicate } = params;\n\n const noneSpecified = !contract && !script && !predicate;\n\n if (contract || noneSpecified) {\n return ProgramTypeEnum.CONTRACT;\n }\n\n if (predicate) {\n return ProgramTypeEnum.PREDICATE;\n }\n\n return ProgramTypeEnum.SCRIPT;\n}\n\nexport function runCliAction(options: ICliParams) {\n const { inputs, output, silent, contract, script, predicate } = options;\n\n const cwd = process.cwd();\n\n const programType = resolveProgramType({ contract, script, predicate });\n\n try {\n runTypegen({\n cwd,\n inputs,\n output,\n programType,\n silent: !!silent,\n });\n } catch (err) {\n process.stderr.write(`error: ${(<Error>err).message}\\n`);\n process.exit(1);\n }\n}\n\nexport function configureCliOptions(program: Command) {\n return program\n .requiredOption('-i, --inputs <path|glob...>', 'Input paths/globals to your ABI JSON files')\n .requiredOption('-o, --output <dir>', 'Directory path for generated files')\n .addOption(\n new Option('-c, --contract', 'Generate types for Contracts [default]')\n .conflicts(['script', 'predicate'])\n .implies({ script: undefined, predicate: undefined })\n )\n .addOption(\n new Option('-s, --script', 'Generate types for Scripts')\n .conflicts(['contract', 'predicate'])\n .implies({ contract: undefined, predicate: undefined })\n )\n .addOption(\n new Option('-p, --predicate', 'Generate types for Predicates')\n .conflicts(['contract', 'script'])\n .implies({ contract: undefined, script: undefined })\n )\n .option('-S, --silent', 'Omit output messages')\n .action(runCliAction);\n}\n\nexport function run(params: { argv: string[]; programName: string }) {\n const program = new Command();\n\n const { argv, programName } = params;\n\n program.name(programName);\n program.version(versions.FUELS);\n program.usage(`-i ../out/*-abi.json -o ./generated/`);\n\n configureCliOptions(program);\n\n program.parse(argv);\n}\n","import { ErrorCode, FuelError } from '@fuel-ts/errors';\nimport { readFileSync, writeFileSync } from 'fs';\nimport { globSync } from 'glob';\nimport mkdirp from 'mkdirp';\nimport { basename } from 'path';\nimport rimraf from 'rimraf';\n\nimport { AbiTypeGen } from './AbiTypeGen';\nimport type { ProgramTypeEnum } from './types/enums/ProgramTypeEnum';\nimport type { IFile } from './types/interfaces/IFile';\nimport { collectBinFilepaths } from './utils/collectBinFilePaths';\nimport { collectStorageSlotsFilepaths } from './utils/collectStorageSlotsFilePaths';\n\nexport interface IGenerateFilesParams {\n cwd: string;\n filepaths?: string[];\n inputs?: string[];\n output: string;\n silent?: boolean;\n programType: ProgramTypeEnum;\n}\n\nexport function runTypegen(params: IGenerateFilesParams) {\n const { cwd, inputs, output, silent, programType, filepaths: inputFilepaths } = params;\n\n const cwdBasename = basename(cwd);\n\n function log(...args: unknown[]) {\n if (!silent) {\n process.stdout.write(`${args.join(' ')}\\n`);\n }\n }\n\n /*\n Assembling files array and expanding globals if needed\n */\n let filepaths: string[] = [];\n\n if (!inputFilepaths?.length && inputs?.length) {\n filepaths = inputs.flatMap((i) => globSync(i, { cwd }));\n } else if (inputFilepaths?.length) {\n filepaths = inputFilepaths;\n } else {\n throw new FuelError(\n ErrorCode.MISSING_REQUIRED_PARAMETER,\n `At least one parameter should be supplied: 'input' or 'filepaths'.`\n );\n }\n\n /*\n Assembling file paths x contents\n */\n const abiFiles = filepaths.map((filepath) => {\n const abi: IFile = {\n path: filepath,\n contents: readFileSync(filepath, 'utf-8'),\n };\n return abi;\n });\n\n if (!abiFiles.length) {\n throw new FuelError(ErrorCode.NO_ABIS_FOUND, `no ABI found at '${inputs}'`);\n }\n\n const binFiles = collectBinFilepaths({ filepaths, programType });\n\n const storageSlotsFiles = collectStorageSlotsFilepaths({ filepaths, programType });\n\n /*\n Starting the engine\n */\n const abiTypeGen = new AbiTypeGen({\n outputDir: output,\n abiFiles,\n binFiles,\n storageSlotsFiles,\n programType,\n });\n\n /*\n Generating files\n */\n log('Generating files..\\n');\n\n mkdirp.sync(`${output}/factories`);\n\n abiTypeGen.files.forEach((file) => {\n rimraf.sync(file.path);\n writeFileSync(file.path, file.contents);\n const trimPathRegex = new RegExp(`^.+${cwdBasename}/`, 'm');\n log(` - ${file.path.replace(trimPathRegex, '')}`);\n });\n\n log('\\nDone.⚡');\n}\n","import { ErrorCode, FuelError } from '@fuel-ts/errors';\n\nimport { Abi } from './abi/Abi';\nimport { ProgramTypeEnum } from './types/enums/ProgramTypeEnum';\nimport type { IFile } from './types/interfaces/IFile';\nimport { assembleContracts } from './utils/assembleContracts';\nimport { assemblePredicates } from './utils/assemblePredicates';\nimport { assembleScripts } from './utils/assembleScripts';\nimport { validateBinFile } from './utils/validateBinFile';\n\n/*\n Manages many instances of Abi\n*/\nexport class AbiTypeGen {\n public readonly abis: Abi[];\n public readonly abiFiles: IFile[];\n public readonly binFiles: IFile[];\n public readonly storageSlotsFiles: IFile[];\n public readonly outputDir: string;\n\n public readonly files: IFile[];\n\n constructor(params: {\n abiFiles: IFile[];\n binFiles: IFile[];\n storageSlotsFiles: IFile[];\n outputDir: string;\n programType: ProgramTypeEnum;\n }) {\n const { abiFiles, binFiles, outputDir, programType, storageSlotsFiles } = params;\n\n this.outputDir = outputDir;\n\n this.abiFiles = abiFiles;\n this.binFiles = binFiles;\n this.storageSlotsFiles = storageSlotsFiles;\n\n // Creates a `Abi` for each abi file\n this.abis = this.abiFiles.map((abiFile) => {\n const binFilepath = abiFile.path.replace('-abi.json', '.bin');\n const relatedBinFile = this.binFiles.find(({ path }) => path === binFilepath);\n\n const storageSlotFilepath = abiFile.path.replace('-abi.json', '-storage_slots.json');\n const relatedStorageSlotsFile = this.storageSlotsFiles.find(\n ({ path }) => path === storageSlotFilepath\n );\n\n if (!relatedBinFile) {\n validateBinFile({\n abiFilepath: abiFile.path,\n binExists: !!relatedBinFile,\n binFilepath,\n programType,\n });\n }\n\n const abi = new Abi({\n filepath: abiFile.path,\n rawContents: JSON.parse(abiFile.contents as string),\n hexlifiedBinContents: relatedBinFile?.contents,\n storageSlotsContents: relatedStorageSlotsFile?.contents,\n outputDir,\n programType,\n });\n\n return abi;\n });\n\n // Assemble list of files to be written to disk\n this.files = this.getAssembledFiles({ programType });\n }\n\n private getAssembledFiles(params: { programType: ProgramTypeEnum }): IFile[] {\n const { abis, outputDir } = this;\n const { programType } = params;\n\n switch (programType) {\n case ProgramTypeEnum.CONTRACT:\n return assembleContracts({ abis, outputDir });\n case ProgramTypeEnum.SCRIPT:\n return assembleScripts({ abis, outputDir });\n case ProgramTypeEnum.PREDICATE:\n return assemblePredicates({ abis, outputDir });\n default:\n throw new FuelError(\n ErrorCode.INVALID_INPUT_PARAMETERS,\n `Invalid Typegen programType: ${programType}. Must be one of ${Object.values(\n ProgramTypeEnum\n )}`\n );\n }\n }\n}\n","import { ErrorCode, FuelError } from '@fuel-ts/errors';\nimport { normalizeString } from '@fuel-ts/utils';\n\nimport type { ProgramTypeEnum } from '../types/enums/ProgramTypeEnum';\nimport type { IConfigurable } from '../types/interfaces/IConfigurable';\nimport type { IFunction } from '../types/interfaces/IFunction';\nimport type { IRawAbi } from '../types/interfaces/IRawAbi';\nimport type { IType } from '../types/interfaces/IType';\nimport { parseConfigurables } from '../utils/parseConfigurables';\nimport { parseFunctions } from '../utils/parseFunctions';\nimport { parseTypes } from '../utils/parseTypes';\n\n/*\n Manages many instances of Types and Functions\n*/\nexport class Abi {\n public name: string;\n public programType: ProgramTypeEnum;\n\n public filepath: string;\n public outputDir: string;\n\n public commonTypesInUse: string[] = [];\n\n public rawContents: IRawAbi;\n public hexlifiedBinContents?: string;\n public storageSlotsContents?: string;\n\n public types: IType[];\n public functions: IFunction[];\n public configurables: IConfigurable[];\n\n constructor(params: {\n filepath: string;\n programType: ProgramTypeEnum;\n rawContents: IRawAbi;\n hexlifiedBinContents?: string;\n storageSlotsContents?: string;\n outputDir: string;\n }) {\n const {\n filepath,\n outputDir,\n rawContents,\n hexlifiedBinContents,\n programType,\n storageSlotsContents,\n } = params;\n\n const abiNameRegex = /([^/]+)-abi\\.json$/m;\n const abiName = filepath.match(abiNameRegex);\n\n const couldNotParseName = !abiName || abiName.length === 0;\n\n if (couldNotParseName) {\n throw new FuelError(\n ErrorCode.PARSE_FAILED,\n `Could not parse name from ABI file: ${filepath}.`\n );\n }\n\n const name = `${normalizeString(abiName[1])}Abi`;\n\n this.name = name;\n this.programType = programType;\n\n this.filepath = filepath;\n this.rawContents = rawContents;\n this.hexlifiedBinContents = hexlifiedBinContents;\n this.storageSlotsContents = storageSlotsContents;\n this.outputDir = outputDir;\n\n const { types, functions, configurables } = this.parse();\n\n this.types = types;\n this.functions = functions;\n this.configurables = configurables;\n\n this.computeCommonTypesInUse();\n }\n\n parse() {\n const {\n types: rawAbiTypes,\n functions: rawAbiFunctions,\n configurables: rawAbiConfigurables,\n } = this.rawContents;\n\n const types = parseTypes({ rawAbiTypes });\n const functions = parseFunctions({ rawAbiFunctions, types });\n const configurables = parseConfigurables({ rawAbiConfigurables, types });\n\n return {\n types,\n functions,\n configurables,\n };\n }\n\n computeCommonTypesInUse() {\n const customTypesTable: Record<string, string> = {\n option: 'Option',\n enum: 'Enum',\n vector: 'Vec',\n };\n\n this.commonTypesInUse = [];\n\n Object.keys(customTypesTable).forEach((typeName) => {\n const isInUse = !!this.types.find((t) => t.name === typeName);\n\n if (isInUse) {\n const commonTypeLabel: string = customTypesTable[typeName];\n this.commonTypesInUse.push(commonTypeLabel);\n }\n });\n }\n}\n","import { ErrorCode, FuelError } from '@fuel-ts/errors';\n\nimport type { IType } from '../types/interfaces/IType';\n\nexport function findType(params: { types: IType[]; typeId: number }) {\n const { types, typeId } = params;\n\n const foundType = types.find(({ rawAbiType: { typeId: tid } }) => tid === typeId);\n\n if (!foundType) {\n throw new FuelError(ErrorCode.TYPE_ID_NOT_FOUND, `Type ID not found: ${typeId}.`);\n }\n\n // ensure type attributes is always parsed\n foundType.parseComponentsAttributes({ types });\n\n return foundType;\n}\n","import type { IConfigurable } from '../../types/interfaces/IConfigurable';\nimport type { IRawAbiConfigurable } from '../../types/interfaces/IRawAbiConfigurable';\nimport type { IType } from '../../types/interfaces/IType';\nimport { findType } from '../../utils/findType';\n\nexport class Configurable implements IConfigurable {\n public name: string;\n public type: IType;\n public rawAbiConfigurable: IRawAbiConfigurable;\n\n constructor(params: { types: IType[]; rawAbiConfigurable: IRawAbiConfigurable }) {\n const { types, rawAbiConfigurable } = params;\n\n this.name = rawAbiConfigurable.name;\n this.rawAbiConfigurable = rawAbiConfigurable;\n this.type = findType({ types, typeId: rawAbiConfigurable.configurableType.type });\n }\n}\n","import { Configurable } from '../abi/configurable/Configurable';\nimport type { IRawAbiConfigurable } from '../types/interfaces/IRawAbiConfigurable';\nimport type { IType } from '../types/interfaces/IType';\n\nexport function makeConfigurable(params: {\n types: IType[];\n rawAbiConfigurable: IRawAbiConfigurable;\n}) {\n const { types, rawAbiConfigurable } = params;\n return new Configurable({ types, rawAbiConfigurable });\n}\n","import type { IConfigurable } from '../types/interfaces/IConfigurable';\nimport type { IRawAbiConfigurable } from '../types/interfaces/IRawAbiConfigurable';\nimport type { IType } from '../types/interfaces/IType';\n\nimport { makeConfigurable } from './makeConfigurable';\n\nexport function parseConfigurables(params: {\n types: IType[];\n rawAbiConfigurables: IRawAbiConfigurable[];\n}) {\n const { types, rawAbiConfigurables } = params;\n\n const configurables: IConfigurable[] = rawAbiConfigurables.map((rawAbiConfigurable) =>\n makeConfigurable({ types, rawAbiConfigurable })\n );\n\n return configurables;\n}\n","import type { TargetEnum } from '../types/enums/TargetEnum';\nimport type { IRawAbiTypeComponent } from '../types/interfaces/IRawAbiType';\nimport type { IType } from '../types/interfaces/IType';\n\nimport { findType } from './findType';\n\n/*\n Recursively parses the given `typeArguments` node\n*/\nexport function parseTypeArguments(params: {\n types: IType[];\n target: TargetEnum;\n typeArguments: IRawAbiTypeComponent[];\n parentTypeId?: number;\n}): string {\n const { types, typeArguments, parentTypeId, target } = params;\n\n const attributeKey: 'inputLabel' | 'outputLabel' = `${target}Label`;\n\n const buffer: string[] = [];\n\n let parentType: IType | undefined;\n let parentLabel: string | undefined;\n\n if (parentTypeId !== undefined) {\n parentType = findType({ types, typeId: parentTypeId });\n parentLabel = parentType.attributes[attributeKey];\n }\n\n // loop through all `typeArgument` items\n typeArguments.forEach((typeArgument) => {\n let currentLabel: string;\n\n const currentTypeId = typeArgument.type;\n\n try {\n const currentType = findType({ types, typeId: currentTypeId });\n currentLabel = currentType.attributes[attributeKey];\n } catch (_err) {\n // used for functions without output\n currentLabel = 'void';\n }\n\n if (typeArgument.typeArguments) {\n // recursively process nested `typeArguments`\n const nestedParsed = parseTypeArguments({\n types,\n target,\n parentTypeId: typeArgument.type,\n typeArguments: typeArgument.typeArguments,\n });\n\n buffer.push(nestedParsed);\n } else {\n buffer.push(`${currentLabel}`);\n }\n });\n\n let output = buffer.join(', ');\n\n if (parentLabel) {\n output = `${parentLabel}<${output}>`;\n }\n\n return output;\n}\n","import type { IFunction, IRawAbiFunction, IFunctionAttributes } from '../../index';\nimport { TargetEnum } from '../../types/enums/TargetEnum';\nimport type { IType } from '../../types/interfaces/IType';\nimport { findType } from '../../utils/findType';\nimport { parseTypeArguments } from '../../utils/parseTypeArguments';\n\nexport class Function implements IFunction {\n public name: string;\n public types: IType[];\n public rawAbiFunction: IRawAbiFunction;\n public attributes: IFunctionAttributes;\n\n constructor(params: { types: IType[]; rawAbiFunction: IRawAbiFunction }) {\n this.rawAbiFunction = params.rawAbiFunction;\n this.types = params.types;\n this.name = params.rawAbiFunction.name;\n\n this.attributes = {\n inputs: this.bundleInputTypes(),\n output: this.bundleOutputTypes(),\n prefixedInputs: this.bundleInputTypes(true),\n };\n }\n\n bundleInputTypes(shouldPrefixParams: boolean = false) {\n const { types } = this;\n\n // loop through all inputs\n const inputs = this.rawAbiFunction.inputs.map((input) => {\n const { name, type: typeId, typeArguments } = input;\n\n const type = findType({ types, typeId });\n\n let typeDecl: string;\n\n if (typeArguments) {\n // recursively process child `typeArguments`\n typeDecl = parseTypeArguments({\n types,\n target: TargetEnum.INPUT,\n parentTypeId: typeId,\n typeArguments,\n });\n } else {\n // or just collect type declaration\n typeDecl = type.attributes.inputLabel;\n }\n\n // assemble it in `[key: string]: <Type>` fashion\n if (shouldPrefixParams) {\n return `${name}: ${typeDecl}`;\n }\n\n return typeDecl;\n });\n\n return inputs.join(', ');\n }\n\n bundleOutputTypes() {\n return parseTypeArguments({\n types: this.types,\n target: TargetEnum.OUTPUT,\n typeArguments: [this.rawAbiFunction.output],\n });\n }\n\n getDeclaration() {\n const { name } = this;\n const { prefixedInputs, output } = this.attributes;\n const decl = `${name}: InvokeFunction<[${prefixedInputs}], ${output}>`;\n return decl;\n }\n}\n","import { Function } from '../abi/functions/Function';\nimport type { IRawAbiFunction } from '../types/interfaces/IRawAbiFunction';\nimport type { IType } from '../types/interfaces/IType';\n\nexport function makeFunction(params: { types: IType[]; rawAbiFunction: IRawAbiFunction }) {\n const { types, rawAbiFunction } = params;\n return new Function({ types, rawAbiFunction });\n}\n","import type { IFunction } from '../types/interfaces/IFunction';\nimport type { IRawAbiFunction } from '../types/interfaces/IRawAbiFunction';\nimport type { IType } from '../types/interfaces/IType';\n\nimport { makeFunction } from './makeFunction';\n\nexport function parseFunctions(params: { types: IType[]; rawAbiFunctions: IRawAbiFunction[] }) {\n const { types, rawAbiFunctions } = params;\n const functions: IFunction[] = rawAbiFunctions.map((rawAbiFunction) =>\n makeFunction({ types, rawAbiFunction })\n );\n return functions;\n}\n","import { ErrorCode, FuelError } from '@fuel-ts/errors';\n\nimport type { IRawAbiTypeRoot } from '../types/interfaces/IRawAbiType';\n\nimport { supportedTypes } from './supportedTypes';\n\nexport function makeType(params: { rawAbiType: IRawAbiTypeRoot }) {\n const { rawAbiType } = params;\n const { type } = rawAbiType;\n\n const TypeClass = supportedTypes.find((tc) => tc.isSuitableFor({ type }));\n\n if (!TypeClass) {\n throw new FuelError(ErrorCode.TYPE_NOT_SUPPORTED, `Type not supported: ${type}`);\n }\n\n return new TypeClass(params);\n}\n","import type { IRawAbiTypeRoot } from '../../types/interfaces/IRawAbiType';\nimport type { ITypeAttributes } from '../../types/interfaces/IType';\n\nexport class AType {\n public rawAbiType: IRawAbiTypeRoot;\n public attributes: ITypeAttributes;\n public requiredFuelsMembersImports: string[];\n\n constructor(params: { rawAbiType: IRawAbiTypeRoot }) {\n this.rawAbiType = params.rawAbiType;\n this.attributes = {\n inputLabel: 'unknown',\n outputLabel: 'unknown',\n };\n this.requiredFuelsMembersImports = [];\n }\n}\n","import { TargetEnum } from '../../types/enums/TargetEnum';\nimport type { IType } from '../../types/interfaces/IType';\nimport { findType } from '../../utils/findType';\nimport { parseTypeArguments } from '../../utils/parseTypeArguments';\n\nimport { AType } from './AType';\n\nexport class ArrayType extends AType implements IType {\n // Note: the array length expressed in '; 2]' could be any length\n public static swayType = '[_; 2]';\n\n public name = 'array';\n\n static MATCH_REGEX: RegExp = /^\\[_; ([0-9]+)\\]$/m;\n\n static isSuitableFor(params: { type: string }) {\n return ArrayType.MATCH_REGEX.test(params.type);\n }\n\n public parseComponentsAttributes(params: { types: IType[] }) {\n const { types } = params;\n const { type } = this.rawAbiType;\n\n // array length will be used to generated a fixed-length array type\n const arrayLen = Number(type.match(ArrayType.MATCH_REGEX)?.[1]);\n\n const inputs: string[] = [];\n const outputs: string[] = [];\n\n this.rawAbiType.components?.forEach((component) => {\n const { type: typeId, typeArguments } = component;\n\n if (!typeArguments) {\n // if component has no type arguments, read its attributes and voilà\n const { attributes } = findType({ types, typeId });\n\n inputs.push(attributes.inputLabel);\n outputs.push(attributes.outputLabel);\n } else {\n // otherwise process child `typeArguments` recursively\n const inputLabel = parseTypeArguments({\n types,\n typeArguments,\n parentTypeId: typeId,\n target: TargetEnum.INPUT,\n });\n\n const outputLabel = parseTypeArguments({\n types,\n typeArguments,\n parentTypeId: typeId,\n target: TargetEnum.OUTPUT,\n });\n\n inputs.push(inputLabel);\n outputs.push(outputLabel);\n }\n });\n\n // fixed-length array, based on `arrayLen`\n const inputTypes = Array(arrayLen).fill(inputs[0]).join(', ');\n const outputTypes = Array(arrayLen).fill(outputs[0]).join(', ');\n\n this.attributes = {\n inputLabel: `[${inputTypes}]`,\n outputLabel: `[${outputTypes}]`,\n };\n\n return this.attributes;\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { AType } from './AType';\n\nexport class StrType extends AType implements IType {\n // Note: the str length expressed in '[3]' could be any length\n public static swayType = 'str[3]';\n\n public name = 'str';\n\n static MATCH_REGEX: RegExp = /^str\\[(.+)\\]$/m;\n\n static isSuitableFor(params: { type: string }) {\n return StrType.MATCH_REGEX.test(params.type);\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n this.attributes = {\n inputLabel: 'string',\n outputLabel: 'string',\n };\n return this.attributes;\n }\n}\n","import { StrType } from './StrType';\n\nexport class B256Type extends StrType {\n public static swayType = 'b256';\n\n public name = 'b256';\n\n static MATCH_REGEX = /^b256$/m;\n\n static isSuitableFor(params: { type: string }) {\n return B256Type.MATCH_REGEX.test(params.type);\n }\n}\n","import { B256Type } from './B256Type';\n\nexport class B512Type extends B256Type {\n public static swayType = 'struct B512';\n\n public name = 'b512';\n\n static MATCH_REGEX = /^struct B512$/m;\n\n static isSuitableFor(params: { type: string }) {\n return B512Type.MATCH_REGEX.test(params.type);\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { AType } from './AType';\n\nexport class BoolType extends AType implements IType {\n public static swayType = 'bool';\n\n public name = 'bool';\n\n static MATCH_REGEX: RegExp = /^bool$/m;\n\n static isSuitableFor(params: { type: string }) {\n return BoolType.MATCH_REGEX.test(params.type);\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n this.attributes = {\n inputLabel: 'boolean',\n outputLabel: 'boolean',\n };\n return this.attributes;\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { ArrayType } from './ArrayType';\n\nexport class BytesType extends ArrayType {\n public static swayType = 'struct Bytes';\n\n public name = 'bytes';\n\n static MATCH_REGEX: RegExp = /^struct Bytes/m;\n\n static isSuitableFor(params: { type: string }) {\n return BytesType.MATCH_REGEX.test(params.type);\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n const capitalizedName = 'Bytes';\n\n this.attributes = {\n inputLabel: capitalizedName,\n outputLabel: capitalizedName,\n };\n\n this.requiredFuelsMembersImports = [capitalizedName];\n\n return this.attributes;\n }\n}\n","import { ErrorCode, FuelError } from '@fuel-ts/errors';\n\nimport type { IRawAbiTypeRoot } from '../types/interfaces/IRawAbiType';\n\nexport function extractStructName(params: { rawAbiType: IRawAbiTypeRoot; regex: RegExp }) {\n const { rawAbiType, regex } = params;\n\n const match = rawAbiType.type.match(params.regex)?.[1];\n\n if (!match) {\n let errorMessage = `Couldn't extract struct name with: '${regex}'.\\n\\n`;\n errorMessage += `Check your JSON ABI.\\n\\n[source]\\n`;\n errorMessage += `${JSON.stringify(rawAbiType, null, 2)}`;\n\n throw new FuelError(ErrorCode.JSON_ABI_ERROR, errorMessage);\n }\n\n return match;\n}\n","import type { IRawAbiTypeComponent } from '../../index';\nimport type { TargetEnum } from '../../types/enums/TargetEnum';\nimport type { IType } from '../../types/interfaces/IType';\nimport { extractStructName } from '../../utils/extractStructName';\nimport { findType } from '../../utils/findType';\n\nimport { AType } from './AType';\n\nexport class EnumType extends AType implements IType {\n public static swayType = 'enum MyEnumName';\n\n public name = 'enum';\n\n static MATCH_REGEX: RegExp = /^enum (.+)$/m;\n static IGNORE_REGEX: RegExp = /^enum Option$/m;\n\n static isSuitableFor(params: { type: string }) {\n const isAMatch = EnumType.MATCH_REGEX.test(params.type);\n const shouldBeIgnored = EnumType.IGNORE_REGEX.test(params.type);\n return isAMatch && !shouldBeIgnored;\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n const structName = this.getStructName();\n\n this.attributes = {\n structName,\n inputLabel: `${structName}Input`,\n outputLabel: `${structName}Output`,\n };\n\n return this.attributes;\n }\n\n public getStructName() {\n const name = extractStructName({\n rawAbiType: this.rawAbiType,\n regex: EnumType.MATCH_REGEX,\n });\n return name;\n }\n\n public getNativeEnum(params: { types: IType[] }) {\n const { types } = params;\n\n const typeHash: { [key: number]: IType['rawAbiType'] } = types.reduce(\n (hash, row) => ({\n ...hash,\n [row.rawAbiType.typeId]: row,\n }),\n {}\n );\n\n const { components } = this.rawAbiType;\n\n // `components` array guaranteed to always exist for structs/enums\n const enumComponents = components as IRawAbiTypeComponent[];\n\n if (!enumComponents.every(({ type }) => !typeHash[type])) {\n return undefined;\n }\n\n return enumComponents.map(({ name }) => `${name} = '${name}'`).join(', ');\n }\n\n public getStructContents(params: { types: IType[]; target: TargetEnum }) {\n const { types, target } = params;\n\n const { components } = this.rawAbiType;\n\n // `components` array guaranteed to always exist for structs/enums\n const enumComponents = components as IRawAbiTypeComponent[];\n\n const attributeKey: 'inputLabel' | 'outputLabel' = `${target}Label`;\n\n const contents = enumComponents.map((component) => {\n const { name, type: typeId } = component;\n\n if (typeId === 0) {\n return `${name}: []`;\n }\n\n const { attributes } = findType({ types, typeId });\n return `${name}: ${attributes[attributeKey]}`;\n });\n\n return contents.join(', ');\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { AType } from './AType';\n\nexport class EvmAddressType extends AType implements IType {\n public static swayType = 'struct EvmAddress';\n\n public name = 'evmAddress';\n\n static MATCH_REGEX: RegExp = /^struct EvmAddress$/m;\n\n static isSuitableFor(params: { type: string }) {\n return EvmAddressType.MATCH_REGEX.test(params.type);\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n const capitalizedName = 'EvmAddress';\n\n this.attributes = {\n inputLabel: capitalizedName,\n outputLabel: capitalizedName,\n };\n\n this.requiredFuelsMembersImports = [capitalizedName];\n\n return this.attributes;\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\nimport { extractStructName } from '../../utils/extractStructName';\n\nimport { AType } from './AType';\n\nexport class GenericType extends AType implements IType {\n public static swayType = 'generic T';\n\n public name = 'generic';\n\n static MATCH_REGEX: RegExp = /^generic ([^\\s]+)$/m;\n\n static isSuitableFor(params: { type: string }) {\n return GenericType.MATCH_REGEX.test(params.type);\n }\n\n public getStructName() {\n const name = extractStructName({\n rawAbiType: this.rawAbiType,\n regex: GenericType.MATCH_REGEX,\n });\n return name;\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n const label = this.getStructName();\n\n this.attributes = {\n inputLabel: label,\n outputLabel: label,\n };\n\n return this.attributes;\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { AType } from './AType';\n\nexport class OptionType extends AType implements IType {\n public static swayType = 'enum Option';\n\n public name = 'option';\n\n static MATCH_REGEX: RegExp = /^enum Option$/m;\n\n static isSuitableFor(params: { type: string }) {\n return OptionType.MATCH_REGEX.test(params.type);\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n this.attributes = {\n inputLabel: `Option`,\n outputLabel: `Option`,\n };\n return this.attributes;\n }\n}\n","import type { IRawAbiTypeRoot } from '../../index';\nimport type { IType } from '../../types/interfaces/IType';\n\nimport { AType } from './AType';\n\nexport class U8Type extends AType implements IType {\n public static swayType = 'u8';\n\n public name = 'u8';\n\n public static MATCH_REGEX: RegExp = /^u8$/m;\n\n constructor(params: { rawAbiType: IRawAbiTypeRoot }) {\n super(params);\n this.attributes = {\n inputLabel: `BigNumberish`,\n outputLabel: `number`,\n };\n this.requiredFuelsMembersImports = [this.attributes.inputLabel];\n }\n\n static isSuitableFor(params: { type: string }) {\n return U8Type.MATCH_REGEX.test(params.type);\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n return this.attributes;\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { U8Type } from './U8Type';\n\nexport class U64Type extends U8Type implements IType {\n public static swayType = 'u64';\n\n public name = 'u64';\n\n public static MATCH_REGEX: RegExp = /^u64$/m;\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n this.attributes = {\n inputLabel: `BigNumberish`,\n outputLabel: `BN`,\n };\n this.requiredFuelsMembersImports = Object.values(this.attributes);\n return this.attributes;\n }\n\n static isSuitableFor(params: { type: string }) {\n return U64Type.MATCH_REGEX.test(params.type);\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { U64Type } from './U64Type';\n\nexport class RawUntypedPtr extends U64Type implements IType {\n public static swayType = 'raw untyped ptr';\n\n public name = 'rawUntypedPtr';\n\n public static MATCH_REGEX: RegExp = /^raw untyped ptr$/m;\n\n static isSuitableFor(params: { type: string }) {\n return RawUntypedPtr.MATCH_REGEX.test(params.type);\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { ArrayType } from './ArrayType';\n\nexport class RawUntypedSlice extends ArrayType {\n public static swayType = 'raw untyped slice';\n\n public name = 'rawUntypedSlice';\n\n public static MATCH_REGEX: RegExp = /^raw untyped slice$/m;\n\n static isSuitableFor(params: { type: string }) {\n return RawUntypedSlice.MATCH_REGEX.test(params.type);\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n const capitalizedName = 'RawSlice';\n\n this.attributes = {\n inputLabel: capitalizedName,\n outputLabel: capitalizedName,\n };\n\n this.requiredFuelsMembersImports = [capitalizedName];\n\n return this.attributes;\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { AType } from './AType';\n\nexport class StdStringType extends AType implements IType {\n public static swayType = 'struct String';\n\n public name = 'stdString';\n\n static MATCH_REGEX: RegExp = /^struct String/m;\n\n static isSuitableFor(params: { type: string }) {\n return StdStringType.MATCH_REGEX.test(params.type);\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n const capitalizedName = 'StdString';\n\n this.attributes = {\n inputLabel: capitalizedName,\n outputLabel: capitalizedName,\n };\n\n this.requiredFuelsMembersImports = [capitalizedName];\n\n return this.attributes;\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { AType } from './AType';\n\nexport class StrSliceType extends AType implements IType {\n public static swayType = 'str';\n\n public name = 'strSlice';\n\n static MATCH_REGEX: RegExp = /^str$/m;\n\n static isSuitableFor(params: { type: string }) {\n return StrSliceType.MATCH_REGEX.test(params.type);\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n this.attributes = {\n inputLabel: 'StrSlice',\n outputLabel: 'StrSlice',\n };\n return this.attributes;\n }\n}\n","import type { IRawAbiTypeComponent } from '../../index';\nimport type { TargetEnum } from '../../types/enums/TargetEnum';\nimport type { IType } from '../../types/interfaces/IType';\nimport { extractStructName } from '../../utils/extractStructName';\nimport { findType } from '../../utils/findType';\nimport { parseTypeArguments } from '../../utils/parseTypeArguments';\n\nimport { AType } from './AType';\n\nexport class StructType extends AType implements IType {\n public static swayType = 'struct MyStruct';\n\n public name = 'struct';\n\n static MATCH_REGEX: RegExp = /^struct (.+)$/m;\n static IGNORE_REGEX: RegExp = /^struct (Vec|RawVec|EvmAddress|Bytes|String)$/m;\n\n static isSuitableFor(params: { type: string }) {\n const isAMatch = StructType.MATCH_REGEX.test(params.type);\n const shouldBeIgnored = StructType.IGNORE_REGEX.test(params.type);\n return isAMatch && !shouldBeIgnored;\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n const structName = this.getStructName();\n\n this.attributes = {\n structName,\n inputLabel: `${structName}Input`,\n outputLabel: `${structName}Output`,\n };\n\n return this.attributes;\n }\n\n public getStructName() {\n const name = extractStructName({\n rawAbiType: this.rawAbiType,\n regex: StructType.MATCH_REGEX,\n });\n return name;\n }\n\n public getStructContents(params: { types: IType[]; target: TargetEnum }) {\n const { types, target } = params;\n const { components } = this.rawAbiType;\n\n // `components` array guaranteed to always exist for structs/enums\n const structComponents = components as IRawAbiTypeComponent[];\n\n // loop through all components\n const members = structComponents.map((component) => {\n const { name, type: typeId, typeArguments } = component;\n\n const type = findType({ types, typeId });\n\n let typeDecl: string;\n\n if (typeArguments) {\n // recursively process child `typeArguments`\n typeDecl = parseTypeArguments({\n types,\n target,\n parentTypeId: typeId,\n typeArguments,\n });\n } else {\n // or just collect type declaration\n const attributeKey: 'inputLabel' | 'outputLabel' = `${target}Label`;\n typeDecl = type.attributes[attributeKey];\n }\n\n // assemble it in `[key: string]: <Type>` fashion\n return `${name}: ${typeDecl}`;\n });\n\n return members.join(', ');\n }\n\n public getStructDeclaration(params: { types: IType[] }) {\n const { types } = params;\n const { typeParameters } = this.rawAbiType;\n\n if (typeParameters) {\n const structs = typeParameters.map((typeId) => findType({ types, typeId }));\n\n const labels = structs.map(({ attributes: { inputLabel } }) => inputLabel);\n\n return `<${labels.join(', ')}>`;\n }\n\n return '';\n }\n}\n","import { TargetEnum } from '../../types/enums/TargetEnum';\nimport type { IType } from '../../types/interfaces/IType';\nimport { findType } from '../../utils/findType';\nimport { parseTypeArguments } from '../../utils/parseTypeArguments';\n\nimport { AType } from './AType';\n\nexport class TupleType extends AType implements IType {\n // Note: a tuple can have more/less than 3x items (like the one bellow)\n public static swayType = '(_, _, _)';\n\n public name = 'tupple';\n\n static MATCH_REGEX: RegExp = /^\\([_,\\s]+\\)$/m;\n\n static isSuitableFor(params: { type: string }) {\n return TupleType.MATCH_REGEX.test(params.type);\n }\n\n public parseComponentsAttributes(params: { types: IType[] }) {\n const { types } = params;\n\n const inputs: string[] = [];\n const outputs: string[] = [];\n\n this.rawAbiType.components?.forEach((component) => {\n const { type: typeId, typeArguments } = component;\n\n if (!typeArguments) {\n // if component has no type arguments, read its attributes and voilà\n const { attributes } = findType({ types, typeId });\n\n inputs.push(attributes.inputLabel);\n outputs.push(attributes.outputLabel);\n } else {\n // otherwise process child `typeArguments` recursively\n const inputLabel = parseTypeArguments({\n types,\n typeArguments,\n parentTypeId: typeId,\n target: TargetEnum.INPUT,\n });\n\n const outputLabel = parseTypeArguments({\n types,\n typeArguments,\n parentTypeId: typeId,\n target: TargetEnum.OUTPUT,\n });\n\n inputs.push(inputLabel);\n outputs.push(outputLabel);\n }\n });\n\n this.attributes = {\n inputLabel: `[${inputs.join(', ')}]`,\n outputLabel: `[${outputs.join(', ')}]`,\n };\n\n return this.attributes;\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { U8Type } from './U8Type';\n\nexport class U16Type extends U8Type implements IType {\n public static swayType = 'u16';\n\n public name = 'u16';\n\n public static MATCH_REGEX: RegExp = /^u16$/m;\n\n static isSuitableFor(params: { type: string }) {\n return U16Type.MATCH_REGEX.test(params.type);\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { U64Type } from './U64Type';\n\nexport class U256Type extends U64Type implements IType {\n public static swayType = 'u256';\n\n public name = 'u256';\n\n public static MATCH_REGEX: RegExp = /^u256$/m;\n\n static isSuitableFor(params: { type: string }) {\n return U256Type.MATCH_REGEX.test(params.type);\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { U8Type } from './U8Type';\n\nexport class U32Type extends U8Type implements IType {\n public static swayType = 'u32';\n\n public name = 'u32';\n\n public static MATCH_REGEX: RegExp = /^u32$/m;\n\n static isSuitableFor(params: { type: string }) {\n return U32Type.MATCH_REGEX.test(params.type);\n }\n}\n","import type { IType } from '../../types/interfaces/IType';\n\nimport { ArrayType } from './ArrayType';\n\nexport class VectorType extends ArrayType {\n public static swayType = 'struct Vec';\n\n public name = 'vector';\n\n static MATCH_REGEX: RegExp = /^struct Vec/m;\n static IGNORE_REGEX: RegExp = /^struct RawVec$/m;\n\n static isSuitableFor(params: { type: string }) {\n const isAMatch = VectorType.MATCH_REGEX.test(params.type);\n const shouldBeIgnored = VectorType.IGNORE_REGEX.test(params.type);\n return isAMatch && !shouldBeIgnored;\n }\n\n public parseComponentsAttributes(_params: { types: IType[] }) {\n this.attributes = {\n inputLabel: `Vec`,\n outputLabel: `Vec`,\n };\n return this.attributes;\n }\n}\n","import { ArrayType } from '../abi/types/ArrayType';\nimport { B256Type } from '../abi/types/B256Type';\nimport { B512Type } from '../abi/types/B512Type';\nimport { BoolType } from '../abi/types/BoolType';\nimport { BytesType } from '../abi/types/BytesType';\nimport { EnumType } from '../abi/types/EnumType';\nimport { EvmAddressType } from '../abi/types/EvmAddressType';\nimport { GenericType } from '../abi/types/GenericType';\nimport { OptionType } from '../abi/types/OptionType';\nimport { RawUntypedPtr } from '../abi/types/RawUntypedPtr';\nimport { RawUntypedSlice } from '../abi/types/RawUntypedSlice';\nimport { StdStringType } from '../abi/types/StdStringType';\nimport { StrSliceType } from '../abi/types/StrSliceType';\nimport { StrType } from '../abi/types/StrType';\nimport { StructType } from '../abi/types/StructType';\nimport { TupleType } from '../abi/types/TupleType';\nimport { U16Type } from '../abi/types/U16Type';\nimport { U256Type } from '../abi/types/U256Type';\nimport { U32Type } from '../abi/types/U32Type';\nimport { U64Type } from '../abi/types/U64Type';\nimport { U8Type } from '../abi/types/U8Type';\nimport { VectorType } from '../abi/types/VectorType';\n\nexport const supportedTypes = [\n ArrayType,\n B256Type,\n B512Type,\n BoolType,\n BytesType,\n EnumType,\n GenericType,\n OptionType,\n RawUntypedPtr,\n RawUntypedSlice,\n StdStringType,\n StrType,\n StrSliceType,\n StructType,\n TupleType,\n U16Type,\n U32Type,\n U64Type,\n U256Type,\n U8Type,\n VectorType,\n EvmAddressType,\n];\n","export function shouldSkipAbiType(params: { type: string }) {\n const ignoreList = ['()', 'struct RawVec'];\n const shouldSkip = ignoreList.indexOf(params.type) >= 0;\n return shouldSkip;\n}\n","import type { IRawAbiTypeRoot } from '../types/interfaces/IRawAbiType';\nimport type { IType } from '../types/interfaces/IType';\n\nimport { makeType } from './makeType';\nimport { shouldSkipAbiType } from './shouldSkipAbiType';\n\nexport function parseTypes(params: { rawAbiTypes: IRawAbiTypeRoot[] }) {\n const types: IType[] = [];\n\n // First we parse all ROOT nodes\n params.rawAbiTypes.forEach((rawAbiType) => {\n const { type } = rawAbiType;\n const skip = shouldSkipAbiType({ type });\n if (!skip) {\n const parsedType = makeType({ rawAbiType });\n types.push(parsedType);\n }\n });\n\n // Then we parse all their components' [attributes]\n types.forEach((type) => {\n type.parseComponentsAttributes({ types });\n });\n\n return types;\n}\n","export enum ProgramTypeEnum {\n CONTRACT = 'contract',\n SCRIPT = 'script',\n PREDICATE = 'predicate',\n}\n","import { join } from 'path';\n\nimport type { Abi } from '../abi/Abi';\nimport type { IFile } from '../index';\nimport { renderCommonTemplate } from '../templates/common/common';\nimport { renderIndexTemplate } from '../templates/common/index';\nimport { renderBytecodeTemplate } from '../templates/contract/bytecode';\nimport { renderDtsTemplate } from '../templates/contract/dts';\nimport { renderFactoryTemplate } from '../templates/contract/factory';\n\n/**\n * Render all Contract-related templates and returns\n * an array of `IFile` with them all. For here on,\n * the only thing missing is to write them to disk.\n */\nexport function assembleContracts(params: { abis: Abi[]; outputDir: string }) {\n const { abis, outputDir } = params;\n\n const files: IFile[] = [];\n const usesCommonTypes = abis.find((a) => a.commonTypesInUse.length > 0);\n\n abis.forEach((abi) => {\n const { name } = abi;\n\n const dtsFilepath = `${outputDir}/${name}.d.ts`;\n const factoryFilepath = `${outputDir}/factories/${name}__factory.ts`;\n const hexBinFilePath = `${outputDir}/${name}.hex.ts`;\n\n const dts: IFile = {\n path: dtsFilepath,\n contents: renderDtsTemplate({ abi }),\n };\n\n const factory: IFile = {\n path: factoryFilepath,\n contents: renderFactoryTemplate({ abi }),\n };\n\n const hexBinFile: IFile = {\n path: hexBinFilePath,\n contents: renderBytecodeTemplate({\n hexlifiedBytecode: abi.hexlifiedBinContents as string,\n }),\n };\n\n files.push(dts);\n files.push(factory);\n files.push(hexBinFile);\n });\n\n // Includes index file\n const indexFile: IFile = {\n path: `${outputDir}/index.ts`,\n contents: renderIndexTemplate({ abis }),\n };\n\n files.push(indexFile);\n\n // Conditionally includes `common.d.ts` file if needed\n if (usesCommonTypes) {\n const commonsFilepath = join(outputDir, 'common.d.ts');\n const file: IFile = {\n path: commonsFilepath,\n contents: renderCommonTemplate(),\n };\n files.push(file);\n }\n\n return files;\n}\n","import { versions } from '@fuel-ts/versions';\nimport { compile } from 'handlebars';\n\nimport headerTemplate from './common/_header.hbs';\n\n/*\n Renders the given template w/ the given data, while injecting common\n header for disabling lint rules and annotating Fuel component's versions.\n*/\nexport function renderHbsTemplate(params: { template: string; data?: Record<string, unknown> }) {\n const { data, template } = params;\n\n const options = {\n strict: true,\n noEscape: true,\n };\n\n const renderTemplate = compile(template, options);\n const renderHeaderTemplate = compile(headerTemplate, options);\n\n const text = renderTemplate({\n ...data,\n header: renderHeaderTemplate(versions),\n });\n\n return text.replace(/[\\n]{3,}/gm, '\\n\\n');\n}\n","import { renderHbsTemplate } from '../renderHbsTemplate';\n\nimport commonTemplate from './common.hbs';\n\nexport function renderCommonTemplate() {\n const text = renderHbsTemplate({ template: commonTemplate });\n return text;\n}\n","import type { Abi } from '../../abi/Abi';\nimport { ProgramTypeEnum } from '../../types/enums/ProgramTypeEnum';\nimport { renderHbsTemplate } from '../renderHbsTemplate';\n\nimport indexTemplate from './index.hbs';\n\nexport function renderIndexTemplate(params: { abis: Abi[] }) {\n const { abis } = params;\n\n const isGeneratingContracts = abis[0].programType === ProgramTypeEnum.CONTRACT;\n\n const text = renderHbsTemplate({\n template: indexTemplate,\n data: { abis, isGeneratingContracts },\n });\n\n return text;\n}\n","import type { BytesLike } from '@fuel-ts/interfaces';\n\nimport { renderHbsTemplate } from '../renderHbsTemplate';\n\nimport bytecodeTemplate from './bytecode.hbs';\n\nexport function renderBytecodeTemplate(params: { hexlifiedBytecode: BytesLike }) {\n const text = renderHbsTemplate({\n template: bytecodeTemplate,\n data: {\n hexlifiedBytecode: params.hexlifiedBytecode,\n },\n });\n\n return text;\n}\n","import type { IConfigurable } from '../../types/interfaces/IConfigurable';\n\nexport function formatConfigurables(params: { configurables: IConfigurable[] }) {\n const { configurables } = params;\n\n const formattedConfigurables = configurables.map((c) => {\n const {\n name,\n type: {\n attribu