From 136c27288dc35d12792b6e7310de026db2390202 Mon Sep 17 00:00:00 2001 From: juliopavila Date: Mon, 19 Aug 2024 17:20:47 -0300 Subject: [PATCH] feat: refactor hardhat tasks --- packages/contracts/hardhat.config.ts | 3 +- packages/contracts/package.json | 16 +- packages/contracts/tasks/create-EIP1193.ts | 19 ++ .../contracts/tasks/deploy-mastercopies.ts | 21 ++ packages/contracts/tasks/deploy-mastercopy.ts | 101 +++--- packages/contracts/tasks/setup.ts | 304 ------------------ .../contracts/tasks/verify-mastercopies.ts | 21 ++ packages/contracts/tasks/verify-mastercopy.ts | 118 +++++-- packages/contracts/yarn.lock | 61 ++-- 9 files changed, 243 insertions(+), 421 deletions(-) create mode 100644 packages/contracts/tasks/create-EIP1193.ts create mode 100644 packages/contracts/tasks/deploy-mastercopies.ts delete mode 100644 packages/contracts/tasks/setup.ts create mode 100644 packages/contracts/tasks/verify-mastercopies.ts diff --git a/packages/contracts/hardhat.config.ts b/packages/contracts/hardhat.config.ts index e9a789c..9a2a25e 100644 --- a/packages/contracts/hardhat.config.ts +++ b/packages/contracts/hardhat.config.ts @@ -9,9 +9,10 @@ import type { HttpNetworkUserConfig } from "hardhat/types"; dotenv.config(); const { INFURA_KEY, MNEMONIC, ETHERSCAN_API_KEY, PK } = process.env; -import "./tasks/setup"; +import "./tasks/deploy-mastercopies"; import "./tasks/deploy-mastercopy"; import "./tasks/extract-mastercopy"; +import "./tasks/verify-mastercopies"; import "./tasks/verify-mastercopy"; const DEFAULT_MNEMONIC = diff --git a/packages/contracts/package.json b/packages/contracts/package.json index ca3cde2..a45995e 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -6,10 +6,10 @@ "build": "hardhat compile", "test": "hardhat test", "extract-mastercopy": "yarn run build && yarn hardhat extract:mastercopy", - "deploy-mastercopy": "yarn hardhat deploy:contract --network hardhat", - "deploy-last-mastercopy": "yarn hardhat deploy:contract --network hardhat --current", + "deploy-mastercopies": "yarn hardhat deploy:mastercopies --network", + "deploy-mastercopy": "yarn hardhat deploy:mastercopy --network", + "verify-mastercopies": "yarn hardhat verify:mastercopies --network", "verify-mastercopy": "yarn hardhat verify:mastercopy --network", - "verify-last-mastercopy": "yarn hardhat verify:mastercopy --network --current", "coverage": "hardhat coverage", "lint": "yarn lint:sol && yarn lint:ts", "lint:sol": "solhint 'contracts/**/*.sol'", @@ -26,8 +26,8 @@ "@gnosis-guild/zodiac-core": "1.1.0", "@nomicfoundation/hardhat-chai-matchers": "^2.0.7", "@nomicfoundation/hardhat-ethers": "^3.0.6", - "@nomicfoundation/hardhat-ignition-ethers": "^0.15.5", "@nomicfoundation/hardhat-ignition": "^0.15.5", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.5", "@nomicfoundation/hardhat-network-helpers": "^1.0.11", "@nomicfoundation/hardhat-toolbox": "^5.0.0", "@nomicfoundation/hardhat-verify": "^2.0.9", @@ -40,17 +40,19 @@ "chai": "4.3.4", "debug": "4.3.2", "dotenv": "10.0.0", + "eslint": "^9.8.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-prettier": "^5.2.1", - "eslint": "^9.8.0", - "hardhat-gas-reporter": "^2.2.0", + "fs": "^0.0.1-security", "hardhat": "^2.22.7", + "hardhat-gas-reporter": "^2.2.0", + "path": "^0.12.7", "prettier": "^3.3.3", "rimraf": "^6.0.0", - "solhint-plugin-prettier": "0.1.0", "solhint": "5.0.2", + "solhint-plugin-prettier": "0.1.0", "solidity-coverage": "^0.8.12", "ts-node": "^10.9.2", "typechain": "^8.1.1", diff --git a/packages/contracts/tasks/create-EIP1193.ts b/packages/contracts/tasks/create-EIP1193.ts new file mode 100644 index 0000000..f3875d0 --- /dev/null +++ b/packages/contracts/tasks/create-EIP1193.ts @@ -0,0 +1,19 @@ +import { EIP1193Provider } from "@gnosis-guild/zodiac-core"; +import { Signer } from "ethers"; +import { EthereumProvider } from "hardhat/types"; + +export function createEIP1193( + provider: EthereumProvider, + signer: Signer +): EIP1193Provider { + return { + request: async ({ method, params }) => { + if (method == "eth_sendTransaction") { + const { hash } = await signer.sendTransaction((params as any[])[0]); + return hash; + } + + return provider.request({ method, params }); + }, + }; +} diff --git a/packages/contracts/tasks/deploy-mastercopies.ts b/packages/contracts/tasks/deploy-mastercopies.ts new file mode 100644 index 0000000..09af8e9 --- /dev/null +++ b/packages/contracts/tasks/deploy-mastercopies.ts @@ -0,0 +1,21 @@ + +import { task } from "hardhat/config"; + +import { + deployAllMastercopies, +} from "@gnosis-guild/zodiac-core"; +import { createEIP1193 } from "./create-EIP1193"; + +task( + "deploy:mastercopies", + "For every version entry on the artifacts file, deploys a mastercopy into the current network" +).setAction(async (_, hre) => { + const [signer] = await hre.ethers.getSigners(); + const provider = createEIP1193(hre.network.provider, signer); + + await deployAllMastercopies({ + provider, + }); +}); + + diff --git a/packages/contracts/tasks/deploy-mastercopy.ts b/packages/contracts/tasks/deploy-mastercopy.ts index 70626d1..adc56d2 100644 --- a/packages/contracts/tasks/deploy-mastercopy.ts +++ b/packages/contracts/tasks/deploy-mastercopy.ts @@ -1,78 +1,73 @@ -import { Signer } from "ethers"; +/** @format */ + import { task, types } from "hardhat/config"; -import { EthereumProvider } from "hardhat/types"; import { EIP1193Provider, deployMastercopy, - deployAllMastercopies, readMastercopy, } from "@gnosis-guild/zodiac-core"; +import { createEIP1193 } from "./create-EIP1193"; task( "deploy:mastercopy", "For every version entry on the artifacts file, deploys a mastercopy into the current network" ) .addOptionalParam( - "contractName", - "The name of the contractName to deploy", + "contractVersion", + "The specific version of the contract to deploy", + "latest", // Default value types.string ) - .addFlag( - "current", - "Deploy the latest version from disk instead of using mastercopies.json" //TODO: Improve the docs - ) - .setAction(async ({ current, contractName }, hre) => { - console.log("contractName", contractName); + .setAction(async ({ contractVersion }, hre) => { const [signer] = await hre.ethers.getSigners(); const provider = createEIP1193(hre.network.provider, signer); - if (current) { - // Logic to deploy the latest version from disk - await deployLatestMastercopyFromDisk(provider, contractName); - } else { - // using mastercopies.json - await deployAllMastercopies({ - provider, - }); - } - }); - -function createEIP1193( - provider: EthereumProvider, - signer: Signer -): EIP1193Provider { - return { - request: async ({ method, params }) => { - if (method == "eth_sendTransaction") { - const { hash } = await signer.sendTransaction((params as any[])[0]); - return hash; - } - return provider.request({ method, params }); - }, - }; -} + // Deploy the contracts based on the provided version + await deployLatestMastercopyFromDisk(provider, contractVersion); + }); async function deployLatestMastercopyFromDisk( provider: EIP1193Provider, - contract: string + version?: string ) { - const latestArtifact = readMastercopy({ - contractName: contract, - }); + const CONTRACTS = [ + "Exit", + "ExitERC20", + "ExitERC721", + "CirculatingSupply", + "CirculatingSupplyERC20", + "CirculatingSupplyERC721", + ]; - const { address, noop } = await deployMastercopy({ - ...latestArtifact, - provider, - }); - const { contractName, contractVersion } = latestArtifact; - if (noop) { - console.log( - `🔄 ${contractName}@${contractVersion}: Already deployed at ${address}` - ); - } else { - console.log( - `🚀 ${contractName}@${contractVersion}: Successfully deployed at ${address}` - ); + for (const contract of CONTRACTS) { + try { + // Read the artifact for the specific contract and version + const artifact = readMastercopy({ + contractName: contract, + contractVersion: version === "latest" ? undefined : version, + }); + + const { address, noop } = await deployMastercopy({ + ...artifact, + provider, + }); + + if (noop) { + console.log( + `🔄 ${artifact.contractName}@${artifact.contractVersion}: Already deployed at ${address}` + ); + } else { + console.log( + `🚀 ${artifact.contractName}@${artifact.contractVersion}: Successfully deployed at ${address}` + ); + } + } catch (error) { + console.error( + `⏭️ Skipping deployment of ${contract}@${version}: Version not found.` + ); + // Skip the current contract if there's an error and continue with the next one + continue; + } } } diff --git a/packages/contracts/tasks/setup.ts b/packages/contracts/tasks/setup.ts deleted file mode 100644 index 9602054..0000000 --- a/packages/contracts/tasks/setup.ts +++ /dev/null @@ -1,304 +0,0 @@ -import { task, types } from "hardhat/config"; -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { - predictProxyAddress, - readMastercopy, - encodeDeployProxy, -} from "@gnosis-guild/zodiac-core"; - -interface FactoryTaskArgs { - proxied: boolean; -} - -interface CirculatingSupplyTaskArgs extends FactoryTaskArgs { - type: "ERC20" | "ERC721"; - owner: string; - token: string; - exclusions: string; -} - -interface ExitSetupArgs extends FactoryTaskArgs { - type: "ERC20" | "ERC721"; - owner: string; - avatar: string; - target: string; - token: string; - supply: string; -} - -const wait = (seconds: number) => - new Promise((resolve) => setTimeout(resolve, seconds * 1000)); - -const deployCirculatingSupply = async ( - taskArgs: CirculatingSupplyTaskArgs, - hardhatRuntime: HardhatRuntimeEnvironment -) => { - const [deployer] = await hardhatRuntime.ethers.getSigners(); - console.log("Using the account:", deployer.address); - const exclusions = taskArgs.exclusions ? taskArgs.exclusions.split(",") : []; - - const contract = - taskArgs.type === "ERC721" - ? "CirculatingSupplyERC721" - : "CirculatingSupply"; - - if (taskArgs.proxied) { - const mastercopyArtifact = readMastercopy({ - contractName: contract, - }); - - const nonce = await deployer.getNonce(); - - const mastercopy = mastercopyArtifact.address; - const setupArgs = { - types: ["address", "address", "address[]"], - values: [taskArgs.owner, taskArgs.token, exclusions], - }; - - const transaction = encodeDeployProxy({ - mastercopy, - setupArgs, - saltNonce: nonce, - }); - const deploymentTransaction = await deployer.sendTransaction(transaction); - await deploymentTransaction.wait(); - - console.log( - "Circulating supply contract deployed to", - predictProxyAddress({ mastercopy, setupArgs, saltNonce: nonce }) - ); - } else { - const Supply = await hardhatRuntime.ethers.getContractFactory(contract); - const supply = await Supply.deploy( - taskArgs.owner, - taskArgs.token, - exclusions - ); - console.log( - "Circulating supply contract deployed to", - await supply.getAddress() - ); - - console.log("Wait 10s to verify contract..."); - wait(10); - - await hardhatRuntime.run("verify:verify", { - address: supply.getAddress(), - constructorArguments: [taskArgs.owner, taskArgs.token, exclusions], - }); - } -}; - -task("deployCirculatingSupply", "Deploy circulating supply contract") - .addParam( - "type", - "Which token type is going to be used ERC20 or ERC721?", - "ERC20", - types.string - ) - .addParam("owner", "Address of the owner", undefined, types.string) - .addParam("token", "Address of the designated token", undefined, types.string) - .addParam( - "exclusions", - "List of address to exclude (e.g: 0xab,0xgm,0xez)", - undefined, - types.string, - true - ) - .addParam( - "proxied", - "Deploys contract through factory", - false, - types.boolean, - true - ) - .setAction(deployCirculatingSupply); - -const setupModule = async ( - taskArgs: ExitSetupArgs, - hardhatRuntime: HardhatRuntimeEnvironment -) => { - const [deployer] = await hardhatRuntime.ethers.getSigners(); - console.log("Using the account:", deployer.address); - - const contract = taskArgs.type === "ERC721" ? "ExitERC721" : "ExitERC20"; - - if (taskArgs.proxied) { - const mastercopyArtifact = readMastercopy({ - contractName: contract, - }); - - const nonce = await deployer.getNonce(); - - const mastercopy = mastercopyArtifact.address; - const setupArgs = { - types: ["address", "address", "address", "address", "address"], - values: [ - taskArgs.owner, - taskArgs.avatar, - taskArgs.target, - taskArgs.token, - taskArgs.supply, - ], - }; - - const transaction = encodeDeployProxy({ - mastercopy, - setupArgs, - saltNonce: nonce, - }); - const deploymentTransaction = await deployer.sendTransaction(transaction); - await deploymentTransaction.wait(); - - console.log( - "Module deployed to: ", - predictProxyAddress({ mastercopy, setupArgs, saltNonce: nonce }) - ); - } else { - const Module = await hardhatRuntime.ethers.getContractFactory(contract); - - const module = await Module.deploy( - taskArgs.owner, - taskArgs.avatar, - taskArgs.target, - taskArgs.token, - taskArgs.supply - ); - console.log("Module deployed to: ", await module.getAddress()); - - console.log("Wait 10s to verify contract..."); - wait(10); - - await hardhatRuntime.run("verify:verify", { - address: await module.getAddress(), - constructorArguments: [ - taskArgs.owner, - taskArgs.avatar, - taskArgs.target, - taskArgs.token, - taskArgs.supply, - ], - }); - } -}; - -task("setup", "deploy a Exit Module") - .addParam( - "type", - "Which token type is going to be used ERC20 or ERC721?", - "ERC20", - types.string - ) - .addParam("owner", "Address of the owner", undefined, types.string) - .addParam( - "avatar", - "Address of the avatar (e.g. Safe)", - undefined, - types.string - ) - .addParam("target", "Address of the target", undefined, types.string) - .addParam("token", "Address of the designated token", undefined, types.string) - .addParam( - "supply", - "Circulating supply of the designated token", - undefined, - types.string - ) - .addParam("proxied", "Deploy module through proxy", false, types.boolean) - .setAction(setupModule); - -task("verifyEtherscan", "Verifies the contract on etherscan") - .addParam("module", "Address of the Safe Exit", undefined, types.string) - .addParam("owner", "Address of the owner", undefined, types.string) - .addParam("target", "Address of the target", undefined, types.string) - .addParam( - "avatar", - "Address of the avatar (e.g. Safe)", - undefined, - types.string - ) - .addParam("token", "Address of the designated token", undefined, types.string) - .addParam( - "supply", - "Address of circulating supply contract", - undefined, - types.string - ) - .setAction(async (taskArgs, hardhatRuntime) => { - await hardhatRuntime.run("verify", { - address: taskArgs.module, - constructorArgsParams: [ - taskArgs.owner, - taskArgs.avatar, - taskArgs.target, - taskArgs.token, - taskArgs.supply, - ], - }); - }); - -const deployDesignatedToken = async ( - taskArgs: { user: string }, - hardhatRuntime: HardhatRuntimeEnvironment -) => { - const [caller] = await hardhatRuntime.ethers.getSigners(); - console.log("Using the account:", caller.address); - - const Token = await hardhatRuntime.ethers.getContractFactory("TestToken"); - const token = await Token.deploy(18); - - await token.deploymentTransaction()?.wait(3); - console.log("Token deployed to:", token.getAddress()); - - const receiver = taskArgs.user || caller.address; - await token.mint(receiver, BigInt(10) ** BigInt(18)); - - console.log("Token minted to:", receiver); - - console.log("Wait 10s to verify contract..."); - wait(10); - await hardhatRuntime.run("verify:verify", { - address: await token.getAddress(), - constructorArguments: [18], - }); -}; - -task("deployDesignatedToken") - .addParam( - "user", - "User that will receive tokens after deployment", - "", - types.string - ) - .setAction(deployDesignatedToken); - -const deployTestTokenERC721 = async ( - taskArgs: Record, - hardhatRuntime: HardhatRuntimeEnvironment -) => { - const [caller] = await hardhatRuntime.ethers.getSigners(); - console.log("Using the account:", caller.address); - - const Token = - await hardhatRuntime.ethers.getContractFactory("TestTokenERC721"); - const token = await Token.deploy(); - - await token.deploymentTransaction()?.wait(3); - console.log("Token deployed to:", token.getAddress()); - - const receiver = taskArgs.user || (await caller.getAddress()); - await token.mint(receiver as string); - - console.log("Token minted to:", receiver); - - console.log("Wait 10s to verify contract..."); - wait(10); - await hardhatRuntime.run("verify:verify", { - address: await token.getAddress(), - constructorArguments: [], - }); -}; - -task("deployTestTokenERC721").setAction(deployTestTokenERC721); - -export {}; diff --git a/packages/contracts/tasks/verify-mastercopies.ts b/packages/contracts/tasks/verify-mastercopies.ts new file mode 100644 index 0000000..c9fceef --- /dev/null +++ b/packages/contracts/tasks/verify-mastercopies.ts @@ -0,0 +1,21 @@ +import { task } from "hardhat/config"; +import { + verifyAllMastercopies, +} from "@gnosis-guild/zodiac-core"; + +const { ETHERSCAN_API_KEY } = process.env; + +task( + "verify:mastercopies", + "Verifies all mastercopies from the artifacts file, in the block explorer corresponding to the current network" +).setAction(async (_, hre) => { + if (!ETHERSCAN_API_KEY) { + throw new Error("Missing ENV ETHERSCAN_API_KEY"); + } + + const chainId = String((await hre.ethers.provider.getNetwork()).chainId); + await verifyAllMastercopies({ + apiUrlOrChainId: chainId, + apiKey: ETHERSCAN_API_KEY, + }); +}); diff --git a/packages/contracts/tasks/verify-mastercopy.ts b/packages/contracts/tasks/verify-mastercopy.ts index 6bff379..ca6b376 100644 --- a/packages/contracts/tasks/verify-mastercopy.ts +++ b/packages/contracts/tasks/verify-mastercopy.ts @@ -5,52 +5,114 @@ import { } from "@gnosis-guild/zodiac-core"; import path from "path"; import fs from "fs"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { cwd } from "process"; const { ETHERSCAN_API_KEY } = process.env; +/** + * Simulates the SDK's `defaultBuildDir` functionality, pointing to the contract artifacts directory. + * + * @returns {string} The absolute path to the contract artifacts directory. + */ +function getBuildDir(): string { + return path.join(cwd(), "build", "artifacts", "contracts"); +} + +/** + * Simulates the SDK's `defaultMastercopyArtifactsFile`, pointing to the mastercopies.json file. + * + * @returns {string} The absolute path to the mastercopy artifacts file. + */ +function getMastercopyArtifactsFile(): string { + return path.join(cwd(), "temp-mastercopies.json"); +} + task( "verify:mastercopy", - "Verifies all mastercopies from the artifacts file, in the block explorer corresponding to the current network" + "Verifies all mastercopies from the artifacts file in the block explorer corresponding to the current network" ) .addOptionalParam( - "contractName", - "The name of the contractName to verify", + "contractVersion", + "The specific version of the contract to deploy", + "latest", // Default value types.string ) - .addFlag( - "current", - "Verify the latest version from disk instead of using mastercopies.json" //TODO: Improve the docs - ) - .setAction(async ({ current, contractName }, hre) => { + .setAction(async ({ contractVersion }, hre) => { if (!ETHERSCAN_API_KEY) { throw new Error("Missing ENV ETHERSCAN_API_KEY"); } const chainId = String((await hre.ethers.provider.getNetwork()).chainId); + await verifyLatestMastercopyFromDisk(hre, chainId, contractVersion); + }); + +/** + * Verifies the latest mastercopy from disk, handling multiple contracts and versions. + * + * @param {HardhatRuntimeEnvironment} hre - The Hardhat runtime environment. + * @param {string} chainId - The chain ID of the network. + * @param {string} [version] - The specific version of the contract to verify. + */ +async function verifyLatestMastercopyFromDisk( + hre: HardhatRuntimeEnvironment, + chainId: string, + version?: string +) { + const CONTRACTS = [ + "Exit", + "ExitERC20", + "ExitERC721", + "CirculatingSupply", + "CirculatingSupplyERC20", + "CirculatingSupplyERC721", + ]; + + const verifyDir = path.dirname(getMastercopyArtifactsFile()); + + // Ensure the directory exists + if (!fs.existsSync(verifyDir)) { + fs.mkdirSync(verifyDir, { recursive: true }); + } + + // Define the mastercopyObject with the appropriate type + const mastercopyObject: { [key: string]: { [version: string]: any } } = {}; - if (current && contractName) { + for (const contract of CONTRACTS) { + try { + // Read the artifact for the specific contract and version const latestArtifact = readMastercopy({ - contractName, + contractName: contract, + contractVersion: version === "latest" ? undefined : version, }); - const tempFilePath = path.join( - hre.config.paths.cache, - "latest-mastercopy.json" - ); - fs.writeFileSync(tempFilePath, JSON.stringify([latestArtifact], null, 2)); - const { address } = latestArtifact; - console.log(`Verifying ${contractName} at address ${address}...`); + if (!latestArtifact) { + console.error( + `⏭️ Skipping verify of ${contract}@${version}: Artifact not found.` + ); + continue; + } - await verifyAllMastercopies({ - apiUrlOrChainId: chainId, - apiKey: ETHERSCAN_API_KEY, - mastercopyArtifactsFile: tempFilePath, - }); - fs.unlinkSync(tempFilePath); - } else { - await verifyAllMastercopies({ - apiUrlOrChainId: chainId, - apiKey: ETHERSCAN_API_KEY, - }); + // Add the contract to the expected structure + mastercopyObject[contract] = { + [latestArtifact.contractVersion]: latestArtifact, + }; + } catch (error) { + console.error( + `⏭️ Skipping deployment of ${contract}@${version}: Version not found.` + ); + continue; } + } + + const tempFilePath = getMastercopyArtifactsFile(); + fs.writeFileSync(tempFilePath, JSON.stringify(mastercopyObject, null, 2)); + + await verifyAllMastercopies({ + apiUrlOrChainId: chainId, + apiKey: ETHERSCAN_API_KEY as string, + mastercopyArtifactsFile: tempFilePath, }); + + fs.unlinkSync(tempFilePath); +} \ No newline at end of file diff --git a/packages/contracts/yarn.lock b/packages/contracts/yarn.lock index ba31310..a7968c4 100644 --- a/packages/contracts/yarn.lock +++ b/packages/contracts/yarn.lock @@ -2573,6 +2573,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fs@^0.0.1-security: + version "0.0.1-security" + resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" + integrity sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w== + fsevents@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" @@ -3085,6 +3090,11 @@ inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" @@ -3966,6 +3976,14 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +path@^0.12.7: + version "0.12.7" + resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" + integrity sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q== + dependencies: + process "^0.11.1" + util "^0.10.3" + pathval@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" @@ -4034,6 +4052,11 @@ prettier@^3.3.3: resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105" integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew== +process@^0.11.1: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + prompts@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -4550,16 +4573,7 @@ string-format@^2.0.0: resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -4612,14 +4626,7 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -5000,6 +5007,13 @@ util-deprecate@^1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" @@ -5104,16 +5118,7 @@ workerpool@^6.5.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==