UNPKG

hardhat

Version:

Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.

125 lines 5.91 kB
import { HardhatError } from "@nomicfoundation/hardhat-errors"; import { getEnvVariableNameFromGlobalOption } from "@nomicfoundation/hardhat-utils/env"; import { ArgumentType } from "../../types/arguments.js"; import { parseArgumentValue, validateArgumentValue, validateArgumentName, validateArgumentShortName, } from "./arguments.js"; /** * Builds a map of the global option definitions by going through all the * plugins and validating the global options they define. * * Note: this function can be used before initializing the HRE, so the plugins * shouldn't be consider validated. Hence, we should validate the global * options. */ export function buildGlobalOptionDefinitions(resolvedPlugins) { const globalOptionDefinitions = new Map(); const globalOptionDefinitionsByShortName = new Map(); for (const plugin of resolvedPlugins) { if (plugin.globalOptions === undefined) { continue; } for (const option of plugin.globalOptions) { const existingByName = globalOptionDefinitions.get(option.name); if (existingByName !== undefined) { throw new HardhatError(HardhatError.ERRORS.CORE.GENERAL.GLOBAL_OPTION_ALREADY_DEFINED, { plugin: plugin.id, globalOption: option.name, definedByPlugin: existingByName.pluginId, }); } if (option.shortName !== undefined) { const existingByShortName = globalOptionDefinitionsByShortName.get(option.shortName); if (existingByShortName !== undefined) { throw new HardhatError(HardhatError.ERRORS.CORE.GENERAL.GLOBAL_OPTION_ALREADY_DEFINED, { plugin: plugin.id, globalOption: option.shortName, definedByPlugin: existingByShortName.pluginId, }); } } const validatedGlobalOption = buildGlobalOptionDefinition(option); const mapEntry = { pluginId: plugin.id, option: validatedGlobalOption, }; globalOptionDefinitions.set(validatedGlobalOption.name, mapEntry); if (validatedGlobalOption.shortName !== undefined) { globalOptionDefinitionsByShortName.set(validatedGlobalOption.shortName, mapEntry); } } } return globalOptionDefinitions; } /** * Builds a global option definition, validating the name, type, and default * value. */ export function buildGlobalOptionDefinition({ name, shortName, description, type, defaultValue, }) { const argumentType = type ?? ArgumentType.STRING; validateArgumentName(name); if (shortName !== undefined) { validateArgumentShortName(shortName); } validateArgumentValue("defaultValue", argumentType, defaultValue); return { name, shortName, description, type: argumentType, defaultValue, }; } /** * Resolves global options by merging user-provided options with environment * variables, adhering to predefined global option definitions. This function * ensures that only options specified in the globalOptionDefinitions are * considered. Each option is validated against its definition in the map, with * user-provided options taking precedence over environment variables. If an * option is not provided by the user or set as an environment variable, its * default value (as specified in the globalOptionDefinitions) is used. * * @param userProvidedGlobalOptions The options explicitly provided by the * user. These take precedence over equivalent environment variables. * @param globalOptionDefinitions A map defining valid global options, their default * values, and expected types. This map is used to validate and parse the options. * @returns {GlobalOptions} An object containing the resolved global options, * with each option adhering to its definition in the globalOptionDefinitions. * @throws {HardhatError} with descriptor * {@link HardhatError.ERRORS.CORE.ARGUMENTS.INVALID_VALUE_FOR_TYPE} if a user-provided * option has an invalid value for its type. */ export function resolveGlobalOptions(userProvidedGlobalOptions, globalOptionDefinitions) { /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- We start with an empty object, and incrementally build a safe GlobalOptions */ const globalOptions = {}; // iterate over the definitions to parse and validate the arguments for (const [name, { option }] of globalOptionDefinitions) { let value = /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- GlobalOptions is empty for user extension, so we need to cast it to assign the value. */ userProvidedGlobalOptions[name]; let parsedValue; // if the value is provided in the user options, it's already parsed // and it takes precedence over env vars if (value !== undefined) { parsedValue = value; } else { value = process.env[getEnvVariableNameFromGlobalOption(name)]; if (value !== undefined) { // if the value is provided via an env var, it needs to be parsed parsedValue = parseArgumentValue(value, option.type, name); } else { // if the value is not provided by the user or env var, use the default parsedValue = option.defaultValue; } } /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- This operation is unsafe, because the GlobalOptions type is augmented by plugins. */ globalOptions[name] = parsedValue; } return globalOptions; } //# sourceMappingURL=global-options.js.map