import pkg from '../../package.json' with { type: 'json' }; import type { AbiExporterConfig, AbiExporterConfigEntry } from '../types.js'; import { Interface } from '@ethersproject/abi'; import { exists, getAllFilesMatching, readUtf8File, remove, } from '@nomicfoundation/hardhat-utils/fs'; import type { HookContext } from 'hardhat/types/hooks'; import path from 'node:path'; const TS_TAG = `// this file was automatically generated by ${pkg.name} - do not modify`; export const clearAbi = async ( context: HookContext, configEntries: AbiExporterConfig, ) => { const entries = configEntries.filter((entry) => entry.clear); await Promise.all(entries.map((entry) => clearAbiGroup(context, entry))); }; const clearAbiGroup = async ( context: HookContext, config: AbiExporterConfigEntry, ) => { const outputDirectory = path.resolve(context.config.paths.root, config.path); if (!(await exists(outputDirectory))) { return; } // recursively get all relevant files from directory const jsonFiles = await getAllFilesMatching( outputDirectory, (absolutePathToFile) => path.extname(absolutePathToFile) === '.json', ); const tsFiles = await getAllFilesMatching( outputDirectory, (absolutePathToFile) => path.extname(absolutePathToFile) === '.ts', ); // validate file contents and delete await Promise.all( jsonFiles.map(async (file) => { const contents = await readUtf8File(file); try { // attempt to parse ABI from file contents new Interface(contents); } catch (e) { // file is not an ABI - do not delete return; } await remove(file); }), ); await Promise.all( tsFiles.map(async (file) => { const contents = await readUtf8File(file); if (!contents.includes(TS_TAG)) { // file was not generated by plugin - do not delete return; } await remove(file); }), ); // delete the directory if it's empty const remainingFiles = await getAllFilesMatching(outputDirectory); if (remainingFiles.length === 0) { await remove(outputDirectory); } };