@wagmi/cli
Version:
Manage and generate code from Ethereum ABIs
211 lines • 10.4 kB
JavaScript
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