UNPKG

@wagmi/cli

Version:

Manage and generate code from Ethereum ABIs

211 lines 10.4 kB
import { pascalCase } from 'change-case'; import { getAddressDocString } from '../utils/getAddressDocString.js'; import { getIsPackageInstalled } from '../utils/packages.js'; export function actions(config = {}) { return { name: 'Action', async run({ contracts }) { const imports = new Set([]); const content = []; const pure = '/*#__PURE__*/'; const actionNames = new Set(); for (const contract of contracts) { let hasReadFunction = false; let hasWriteFunction = false; let hasEvent = false; const readItems = []; const writeItems = []; const eventItems = []; for (const item of contract.abi) { if (item.type === 'function') if (item.stateMutability === 'view' || item.stateMutability === 'pure') { hasReadFunction = true; readItems.push(item); } else { hasWriteFunction = true; writeItems.push(item); } else if (item.type === 'event') { hasEvent = true; eventItems.push(item); } } let innerContent; if (contract.meta.addressName) innerContent = `abi: ${contract.meta.abiName}, address: ${contract.meta.addressName}`; else innerContent = `abi: ${contract.meta.abiName}`; if (hasReadFunction) { const actionName = getActionName(config, actionNames, 'read', contract.name); const docString = genDocString('readContract', contract); const functionName = 'createReadContract'; imports.add(functionName); content.push(`${docString} export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`); const names = new Set(); for (const item of readItems) { if (item.type !== 'function') continue; if (item.stateMutability !== 'pure' && item.stateMutability !== 'view') continue; // Skip overrides since they are captured by same hook if (names.has(item.name)) continue; names.add(item.name); const hookName = getActionName(config, actionNames, 'read', contract.name, item.name); const docString = genDocString('readContract', contract, { name: 'functionName', value: item.name, }); content.push(`${docString} export const ${hookName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`); } } if (hasWriteFunction) { { const actionName = getActionName(config, actionNames, 'write', contract.name); const docString = genDocString('writeContract', contract); const functionName = 'createWriteContract'; imports.add(functionName); content.push(`${docString} export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`); const names = new Set(); for (const item of writeItems) { if (item.type !== 'function') continue; if (item.stateMutability !== 'nonpayable' && item.stateMutability !== 'payable') continue; // Skip overrides since they are captured by same hook if (names.has(item.name)) continue; names.add(item.name); const actionName = getActionName(config, actionNames, 'write', contract.name, item.name); const docString = genDocString('writeContract', contract, { name: 'functionName', value: item.name, }); content.push(`${docString} export const ${actionName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`); } } { const actionName = getActionName(config, actionNames, 'simulate', contract.name); const docString = genDocString('simulateContract', contract); const functionName = 'createSimulateContract'; imports.add(functionName); content.push(`${docString} export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`); const names = new Set(); for (const item of writeItems) { if (item.type !== 'function') continue; if (item.stateMutability !== 'nonpayable' && item.stateMutability !== 'payable') continue; // Skip overrides since they are captured by same hook if (names.has(item.name)) continue; names.add(item.name); const actionName = getActionName(config, actionNames, 'simulate', contract.name, item.name); const docString = genDocString('simulateContract', contract, { name: 'functionName', value: item.name, }); content.push(`${docString} export const ${actionName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`); } } } if (hasEvent) { const actionName = getActionName(config, actionNames, 'watch', contract.name); const docString = genDocString('watchContractEvent', contract); const functionName = 'createWatchContractEvent'; imports.add(functionName); content.push(`${docString} export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`); const names = new Set(); for (const item of eventItems) { if (item.type !== 'event') continue; // Skip overrides since they are captured by same hook if (names.has(item.name)) continue; names.add(item.name); const actionName = getActionName(config, actionNames, 'watch', contract.name, item.name); const docString = genDocString('watchContractEvent', contract, { name: 'eventName', value: item.name, }); content.push(`${docString} export const ${actionName} = ${pure} ${functionName}({ ${innerContent}, eventName: '${item.name}' })`); } } } const importValues = [...imports.values()]; let packageName = '@wagmi/core/codegen'; if (config.overridePackageName) { switch (config.overridePackageName) { case '@wagmi/core': packageName = '@wagmi/core/codegen'; break; case 'wagmi': packageName = 'wagmi/codegen'; break; } } else if (await getIsPackageInstalled({ packageName: 'wagmi' })) packageName = 'wagmi/codegen'; else if (await getIsPackageInstalled({ packageName: '@wagmi/core' })) packageName = '@wagmi/core/codegen'; return { imports: importValues.length ? `import { ${importValues.join(', ')} } from '${packageName}'\n` : '', content: content.join('\n\n'), }; }, }; } function genDocString(actionName, contract, item) { let description = `Wraps __{@link ${actionName}}__ with \`abi\` set to __{@link ${contract.meta.abiName}}__`; if (item) description += ` and \`${item.name}\` set to \`"${item.value}"\``; const docString = getAddressDocString({ address: contract.address }); if (docString) return `/** * ${description} * ${docString} */`; return `/** * ${description} */`; } function getActionName(config, actionNames, type, contractName, itemName) { const ContractName = pascalCase(contractName); const ItemName = itemName ? pascalCase(itemName) : undefined; let actionName; if (typeof config.getActionName === 'function') actionName = config.getActionName({ type, contractName: ContractName, itemName: ItemName, }); else if (typeof config.getActionName === 'string' && type === 'simulate') { actionName = `prepareWrite${ContractName}${ItemName ?? ''}`; } else { actionName = `${type}${ContractName}${ItemName ?? ''}`; if (type === 'watch') actionName = `${actionName}Event`; } if (actionNames.has(actionName)) throw new Error(`Action name "${actionName}" must be unique for contract "${contractName}". Try using \`getActionName\` to create a unique name.`); actionNames.add(actionName); return actionName; } //# sourceMappingURL=actions.js.map