From b23b03c574e6bd8c320e9b666ae8f5c6b812273d Mon Sep 17 00:00:00 2001 From: Ugwuanyi TobeChukwu <39131739+amaify@users.noreply.github.com> Date: Thu, 6 Aug 2026 10:52:42 +0100 Subject: [PATCH 1/5] Upgrade packages with dependabot alert --- package.json | 8 +-- pnpm-lock.yaml | 174 ++++++++++++++++++++++++++----------------------- 2 files changed, 95 insertions(+), 87 deletions(-) diff --git a/package.json b/package.json index 7c70791..a2e571d 100644 --- a/package.json +++ b/package.json @@ -95,14 +95,14 @@ }, "devDependencies": { "@biomejs/biome": "2.4.15", - "@changesets/cli": "^2.31.0", + "@changesets/cli": "^2.31.1", "@playwright/test": "1.61.1", "@types/adm-zip": "^0.5.8", "@types/cli-progress": "^3.11.6", "@types/node": "^26.0.1", "tsup": "^8.5.1", "typescript": "^6.0.3", - "vitest": "^4.1.9" + "vitest": "^4.1.10" }, "dependencies": { "@inquirer/checkbox": "^5.2.1", @@ -110,8 +110,8 @@ "cli-progress": "^3.12.0", "commander": "^15.0.0", "glob": "^13.0.6", - "prool": "^0.2.4", - "tsx": "^4.22.4", + "prool": "^0.2.14", + "tsx": "^4.23.9", "zod": "^4.4.3" }, "overrides": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1031324..db96d94 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,9 +4,6 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false -overrides: - tar: ^7.5.15 - importers: .: @@ -27,11 +24,11 @@ importers: specifier: ^13.0.6 version: 13.0.6 prool: - specifier: ^0.2.4 - version: 0.2.4 + specifier: ^0.2.14 + version: 0.2.14(debug@4.4.3) tsx: - specifier: ^4.22.4 - version: 4.22.4 + specifier: ^4.23.9 + version: 4.23.9 zod: specifier: ^4.4.3 version: 4.4.3 @@ -40,8 +37,8 @@ importers: specifier: 2.4.15 version: 2.4.15 '@changesets/cli': - specifier: ^2.31.0 - version: 2.31.0(@types/node@26.0.1) + specifier: ^2.31.1 + version: 2.31.1(@types/node@26.0.1) '@playwright/test': specifier: 1.61.1 version: 1.61.1 @@ -56,13 +53,13 @@ importers: version: 26.0.1 tsup: specifier: ^8.5.1 - version: 8.5.1(postcss@8.5.22)(tsx@4.22.4)(typescript@6.0.3) + version: 8.5.1(postcss@8.5.22)(tsx@4.23.9)(typescript@6.0.3) typescript: specifier: ^6.0.3 version: 6.0.3 vitest: - specifier: ^4.1.9 - version: 4.1.9(@types/node@26.0.1)(vite@8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.22.4)) + specifier: ^4.1.10 + version: 4.1.10(@types/node@26.0.1)(vite@8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.23.9)) packages: @@ -136,8 +133,8 @@ packages: '@changesets/changelog-git@0.2.1': resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} - '@changesets/cli@2.31.0': - resolution: {integrity: sha512-AhI4enNTgHu2IZr6K4WZyf0EPch4XVMn1yOMFmCD9gsfBGqMYaHXls5HyDv6/CL5axVQABz68eG30eCtbr2wFg==} + '@changesets/cli@2.31.1': + resolution: {integrity: sha512-uO05WTcRBwuVOJVSW8Cmpqw6q0WDL53ajGCMyszutvOe5toOnunbpM4jZzf+qxBOz7i0AzopZ8diBuewjmF40w==} hasBin: true '@changesets/config@3.1.4': @@ -872,11 +869,11 @@ packages: '@types/node@26.0.1': resolution: {integrity: sha512-fc3KiUoBt6kie0N9bIW3E47vZsuaMf0PM2AaUpLCLT0s/LvX1nxAim6Fc049cNxODPpGm6qRAuUOB86SkRuPQw==} - '@vitest/expect@4.1.9': - resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==} + '@vitest/expect@4.1.10': + resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==} - '@vitest/mocker@4.1.9': - resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==} + '@vitest/mocker@4.1.10': + resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -886,20 +883,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.9': - resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==} + '@vitest/pretty-format@4.1.10': + resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==} - '@vitest/runner@4.1.9': - resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==} + '@vitest/runner@4.1.10': + resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==} - '@vitest/snapshot@4.1.9': - resolution: {integrity: sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==} + '@vitest/snapshot@4.1.10': + resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==} - '@vitest/spy@4.1.9': - resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==} + '@vitest/spy@4.1.10': + resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==} - '@vitest/utils@4.1.9': - resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==} + '@vitest/utils@4.1.10': + resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} acorn@8.16.0: resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} @@ -1358,6 +1355,11 @@ packages: resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} engines: {node: '>= 18'} + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + mlly@1.8.2: resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} @@ -1511,8 +1513,8 @@ packages: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} - prool@0.2.4: - resolution: {integrity: sha512-KAGs6e++7MJNQ/vq8Xrk6akz0lRk6AmhuGzSHkluX3kwVj2XjNDDOYSINZwahRv3xfSD0rXYv3iA/2vXw7z47w==} + prool@0.2.14: + resolution: {integrity: sha512-GAu9hAJqIMac/16sHTm//ya8qfqwh0M+czyRcQYlL8daXYHhSfxOCbNv9SFkmRQ1wZhZHDvDtfqNJZmCcwzJaw==} engines: {node: '>=22'} peerDependencies: '@pimlico/alto': '*' @@ -1629,9 +1631,10 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true - tar@7.5.15: - resolution: {integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==} + tar@7.2.0: + resolution: {integrity: sha512-hctwP0Nb4AB60bj8WQgRYaMOuJYRAPMGiQUAotms5igN8ppfQM+IvjQ5HcKu1MaZh2Wy2KWVTe563Yj8dfc14w==} engines: {node: '>=18'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} @@ -1699,8 +1702,8 @@ packages: typescript: optional: true - tsx@4.22.4: - resolution: {integrity: sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==} + tsx@4.23.9: + resolution: {integrity: sha512-6q8uTORRGauQVjqMQnKUucLFoeXZAfw6zKvG35GLbdKWbLdeOtZ3H4mhyA5mxuUd2o2cRTskhj59nLLQseUvUw==} engines: {node: '>=18.0.0'} hasBin: true @@ -1769,20 +1772,20 @@ packages: yaml: optional: true - vitest@4.1.9: - resolution: {integrity: sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==} + vitest@4.1.10: + resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.9 - '@vitest/browser-preview': 4.1.9 - '@vitest/browser-webdriverio': 4.1.9 - '@vitest/coverage-istanbul': 4.1.9 - '@vitest/coverage-v8': 4.1.9 - '@vitest/ui': 4.1.9 + '@vitest/browser-playwright': 4.1.10 + '@vitest/browser-preview': 4.1.10 + '@vitest/browser-webdriverio': 4.1.10 + '@vitest/coverage-istanbul': 4.1.10 + '@vitest/coverage-v8': 4.1.10 + '@vitest/ui': 4.1.10 happy-dom: '*' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1899,7 +1902,7 @@ snapshots: dependencies: '@changesets/types': 6.1.0 - '@changesets/cli@2.31.0(@types/node@26.0.1)': + '@changesets/cli@2.31.1(@types/node@26.0.1)': dependencies: '@changesets/apply-release-plan': 7.1.1 '@changesets/assemble-release-plan': 6.0.10 @@ -2446,44 +2449,44 @@ snapshots: dependencies: undici-types: 8.3.0 - '@vitest/expect@4.1.9': + '@vitest/expect@4.1.10': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.9 - '@vitest/utils': 4.1.9 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.9(vite@8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.22.4))': + '@vitest/mocker@4.1.10(vite@8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.23.9))': dependencies: - '@vitest/spy': 4.1.9 + '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.22.4) + vite: 8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.23.9) - '@vitest/pretty-format@4.1.9': + '@vitest/pretty-format@4.1.10': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.9': + '@vitest/runner@4.1.10': dependencies: - '@vitest/utils': 4.1.9 + '@vitest/utils': 4.1.10 pathe: 2.0.3 - '@vitest/snapshot@4.1.9': + '@vitest/snapshot@4.1.10': dependencies: - '@vitest/pretty-format': 4.1.9 - '@vitest/utils': 4.1.9 + '@vitest/pretty-format': 4.1.10 + '@vitest/utils': 4.1.10 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.9': {} + '@vitest/spy@4.1.10': {} - '@vitest/utils@4.1.9': + '@vitest/utils@4.1.10': dependencies: - '@vitest/pretty-format': 4.1.9 + '@vitest/pretty-format': 4.1.10 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -2719,7 +2722,9 @@ snapshots: mlly: 1.8.2 rollup: 4.60.4 - follow-redirects@1.16.0: {} + follow-redirects@1.16.0(debug@4.4.3): + optionalDependencies: + debug: 4.4.3 fs-extra@7.0.1: dependencies: @@ -2767,10 +2772,10 @@ snapshots: graceful-fs@4.2.11: {} - http-proxy@1.18.1: + http-proxy@1.18.1(debug@4.4.3): dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.16.0 + follow-redirects: 1.16.0(debug@4.4.3) requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -2908,6 +2913,8 @@ snapshots: dependencies: minipass: 7.1.3 + mkdirp@3.0.1: {} + mlly@1.8.2: dependencies: acorn: 8.16.0 @@ -3003,12 +3010,12 @@ snapshots: optionalDependencies: fsevents: 2.3.2 - postcss-load-config@6.0.1(postcss@8.5.22)(tsx@4.22.4): + postcss-load-config@6.0.1(postcss@8.5.22)(tsx@4.23.9): dependencies: lilconfig: 3.1.3 optionalDependencies: postcss: 8.5.22 - tsx: 4.22.4 + tsx: 4.23.9 postcss@8.5.22: dependencies: @@ -3022,14 +3029,14 @@ snapshots: dependencies: parse-ms: 4.0.0 - prool@0.2.4: + prool@0.2.14(debug@4.4.3): dependencies: change-case: 5.4.4 eventemitter3: 5.0.4 execa: 9.6.1 get-port: 7.2.0 - http-proxy: 1.18.1 - tar: 7.5.15 + http-proxy: 1.18.1(debug@4.4.3) + tar: 7.2.0 transitivePeerDependencies: - debug @@ -3163,12 +3170,13 @@ snapshots: tinyglobby: 0.2.16 ts-interface-checker: 0.1.13 - tar@7.5.15: + tar@7.2.0: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 minipass: 7.1.3 minizlib: 3.1.0 + mkdirp: 3.0.1 yallist: 5.0.0 term-size@2.2.1: {} @@ -3210,7 +3218,7 @@ snapshots: tslib@2.8.1: optional: true - tsup@8.5.1(postcss@8.5.22)(tsx@4.22.4)(typescript@6.0.3): + tsup@8.5.1(postcss@8.5.22)(tsx@4.23.9)(typescript@6.0.3): dependencies: bundle-require: 5.1.0(esbuild@0.27.7) cac: 6.7.14 @@ -3221,7 +3229,7 @@ snapshots: fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(postcss@8.5.22)(tsx@4.22.4) + postcss-load-config: 6.0.1(postcss@8.5.22)(tsx@4.23.9) resolve-from: 5.0.0 rollup: 4.60.4 source-map: 0.7.6 @@ -3238,7 +3246,7 @@ snapshots: - tsx - yaml - tsx@4.22.4: + tsx@4.23.9: dependencies: esbuild: 0.28.0 optionalDependencies: @@ -3256,7 +3264,7 @@ snapshots: universalify@0.1.2: {} - vite@8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.22.4): + vite@8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.23.9): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 @@ -3267,29 +3275,29 @@ snapshots: '@types/node': 26.0.1 esbuild: 0.27.7 fsevents: 2.3.3 - tsx: 4.22.4 + tsx: 4.23.9 - vitest@4.1.9(@types/node@26.0.1)(vite@8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.22.4)): + vitest@4.1.10(@types/node@26.0.1)(vite@8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.23.9)): dependencies: - '@vitest/expect': 4.1.9 - '@vitest/mocker': 4.1.9(vite@8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.22.4)) - '@vitest/pretty-format': 4.1.9 - '@vitest/runner': 4.1.9 - '@vitest/snapshot': 4.1.9 - '@vitest/spy': 4.1.9 - '@vitest/utils': 4.1.9 + '@vitest/expect': 4.1.10 + '@vitest/mocker': 4.1.10(vite@8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.23.9)) + '@vitest/pretty-format': 4.1.10 + '@vitest/runner': 4.1.10 + '@vitest/snapshot': 4.1.10 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 obug: 2.1.1 pathe: 2.0.3 - picomatch: 4.0.4 + picomatch: 4.0.5 std-env: 4.1.0 tinybench: 2.9.0 tinyexec: 1.1.2 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.22.4) + vite: 8.0.13(@types/node@26.0.1)(esbuild@0.27.7)(tsx@4.23.9) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 26.0.1 From 0c9b572793ef46a2db23c48f77bc06484e5e40e9 Mon Sep 17 00:00:00 2001 From: Ugwuanyi TobeChukwu <39131739+amaify@users.noreply.github.com> Date: Thu, 6 Aug 2026 13:33:52 +0100 Subject: [PATCH 2/5] [CLI] - Enhance error handling in downloadFile function --- src/cli/entry-point.ts | 5 +++++ src/utils/download-file.ts | 12 ++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/cli/entry-point.ts b/src/cli/entry-point.ts index c8c6526..e7377f6 100644 --- a/src/cli/entry-point.ts +++ b/src/cli/entry-point.ts @@ -103,6 +103,7 @@ export async function clientEntry() { selectedWallets: response as Array, }); + let ACTION_COUNT = 0; for (const { walletName, config, walletPassword, setupFunction, fileList } of _setupFunction) { try { console.info( @@ -171,11 +172,15 @@ export async function clientEntry() { { validateStream: false }, ), ); + if (_setupFunction.length === 1 || ACTION_COUNT === _setupFunction.length - 1) { + process.exit(1); + } } } } } } + ACTION_COUNT++; } }); diff --git a/src/utils/download-file.ts b/src/utils/download-file.ts index 8214170..520b490 100644 --- a/src/utils/download-file.ts +++ b/src/utils/download-file.ts @@ -17,9 +17,14 @@ export async function downloadFile({ url, destination }: DownloadFileArgs) { const response = await fetch(url, { redirect: "follow", signal: controller.signal }); if (!response.ok) { - console.error(styleText("redBright", `❌ Download failed: HTTP ${response.status}`, { validateStream: false })); - controller.abort(); - process.exit(1); + const errorBody = await response.text().catch(() => ""); + console.error( + styleText( + "redBright", + `❌ Download failed: HTTP ${response.status} ${response.statusText}${errorBody ? `\n${errorBody.slice(0, 500)}` : ""}`, + { validateStream: false }, + ), + ); } const totalBytes = parseInt(response.headers.get("content-length") || "0", 10); @@ -53,7 +58,6 @@ export async function downloadFile({ url, destination }: DownloadFileArgs) { }); } catch (error) { console.error(styleText("redBright", `❌ Download failed: ${error}`, { validateStream: false })); - process.exit(1); } finally { clearTimeout(requestTimeout); } From e9384252207c90dae4e47b2e6c6f9650e1c820c6 Mon Sep 17 00:00:00 2001 From: Ugwuanyi TobeChukwu <39131739+amaify@users.noreply.github.com> Date: Thu, 6 Aug 2026 13:40:57 +0100 Subject: [PATCH 3/5] Fix the failing CI --- src/utils/download-file.ts | 1 + src/utils/tests/download-file.test.ts | 96 ++++++++++++++++++++++----- 2 files changed, 80 insertions(+), 17 deletions(-) diff --git a/src/utils/download-file.ts b/src/utils/download-file.ts index 520b490..3641721 100644 --- a/src/utils/download-file.ts +++ b/src/utils/download-file.ts @@ -25,6 +25,7 @@ export async function downloadFile({ url, destination }: DownloadFileArgs) { { validateStream: false }, ), ); + controller.abort(); } const totalBytes = parseInt(response.headers.get("content-length") || "0", 10); diff --git a/src/utils/tests/download-file.test.ts b/src/utils/tests/download-file.test.ts index 160f8cd..08e5623 100644 --- a/src/utils/tests/download-file.test.ts +++ b/src/utils/tests/download-file.test.ts @@ -114,7 +114,7 @@ describe("downloadFile", () => { expect(mockProgressBar.stop).toHaveBeenCalled(); }); - it("should exit with error code 1 when HTTP request fails", async () => { + it("should log the status, status text and error body when the HTTP request fails", async () => { const url = "https://example.com/not-found.txt"; const destination = path.resolve(TEST_DIR, "not-found.txt"); @@ -122,21 +122,68 @@ describe("downloadFile", () => { global.fetch = vi.fn().mockResolvedValue({ ok: false, status: 404, + statusText: "Not Found", headers: new Headers(), + text: vi.fn().mockResolvedValue("Resource not found"), }); - const exitSpy = vi.spyOn(process, "exit").mockImplementation((code) => { - expect(code).toBe(1); - throw new Error("process.exit called"); + const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + + await expect(downloadFile({ url, destination })).rejects.toThrow(); + + expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining("❌ Download failed: HTTP 404 Not Found")); + expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining("Resource not found")); + + // Verify the in-flight request was aborted + const fetchMock = global.fetch as unknown as ReturnType; + const { signal } = fetchMock.mock.calls[0][1] as { signal: AbortSignal }; + expect(signal.aborted).toBe(true); + + consoleErrorSpy.mockRestore(); + }); + + it("should truncate the error body to 500 characters when the HTTP request fails", async () => { + const url = "https://example.com/server-error.txt"; + const destination = path.resolve(TEST_DIR, "server-error.txt"); + const longBody = "x".repeat(1000); + + global.fetch = vi.fn().mockResolvedValue({ + ok: false, + status: 500, + statusText: "Internal Server Error", + headers: new Headers(), + text: vi.fn().mockResolvedValue(longBody), }); const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); - await expect(downloadFile({ url, destination })).rejects.toThrow("process.exit called"); + await expect(downloadFile({ url, destination })).rejects.toThrow(); - expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining(`❌ Download failed: HTTP 404`)); + expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining("x".repeat(500))); + expect(consoleErrorSpy).not.toHaveBeenCalledWith(expect.stringContaining("x".repeat(501))); + + consoleErrorSpy.mockRestore(); + }); + + it("should omit the error body when reading it fails", async () => { + const url = "https://example.com/unreadable-body.txt"; + const destination = path.resolve(TEST_DIR, "unreadable-body.txt"); + + global.fetch = vi.fn().mockResolvedValue({ + ok: false, + status: 502, + statusText: "Bad Gateway", + headers: new Headers(), + text: vi.fn().mockRejectedValue(new Error("body stream error")), + }); + + const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + + await expect(downloadFile({ url, destination })).rejects.toThrow(); + + expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining("❌ Download failed: HTTP 502 Bad Gateway")); + expect(consoleErrorSpy).not.toHaveBeenCalledWith(expect.stringContaining("\n")); - exitSpy.mockRestore(); consoleErrorSpy.mockRestore(); }); @@ -153,10 +200,6 @@ describe("downloadFile", () => { body: Readable.toWeb(Readable.from(contentBuffer)) as ReadableStream, }); - const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { - throw new Error("process.exit called"); - }); - await expect(downloadFile({ url, destination })).resolves.toBeUndefined(); // Get the progress bar instance that was created @@ -171,8 +214,6 @@ describe("downloadFile", () => { expect(fs.existsSync(destination)).toBe(true); const fileContent = fs.readFileSync(destination, "utf-8"); expect(fileContent).toBe(content); - - exitSpy.mockRestore(); }); it("should handle timeout and abort the request", async () => { @@ -184,12 +225,33 @@ describe("downloadFile", () => { abortError.name = "AbortError"; global.fetch = vi.fn().mockRejectedValue(abortError); - const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { - throw new Error("process.exit called"); + await expect(downloadFile({ url, destination })).rejects.toThrow("The operation was aborted"); + }); + + it("should log the error and resolve when writing to the destination fails", async () => { + const url = "https://example.com/file.txt"; + // Destination inside a directory that does not exist, so the write stream errors + const destination = path.resolve(TEST_DIR, "missing-dir", "file.txt"); + const contentBuffer = Buffer.from("Hello, World!"); + + global.fetch = vi.fn().mockResolvedValue({ + ok: true, + status: 200, + headers: new Headers({ + "content-length": contentBuffer.length.toString(), + }), + body: Readable.toWeb(Readable.from(contentBuffer)) as ReadableStream, }); - await expect(downloadFile({ url, destination })).rejects.toThrow(); + const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + const clearTimeoutSpy = vi.spyOn(global, "clearTimeout"); - exitSpy.mockRestore(); + await expect(downloadFile({ url, destination })).resolves.toBeUndefined(); + + expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining("❌ Download failed:")); + expect(clearTimeoutSpy).toHaveBeenCalled(); + + consoleErrorSpy.mockRestore(); + clearTimeoutSpy.mockRestore(); }); }); From 4af0c843e2890d5b8ed444c25fa5f7fa6cab4dfd Mon Sep 17 00:00:00 2001 From: Ugwuanyi TobeChukwu <39131739+amaify@users.noreply.github.com> Date: Thu, 6 Aug 2026 13:51:30 +0100 Subject: [PATCH 4/5] Fix failing CI --- package.json | 6 +++--- pnpm-lock.yaml | 20 +++++++------------- src/utils/tests/download-file.test.ts | 8 +++++--- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index a2e571d..18bdbf3 100644 --- a/package.json +++ b/package.json @@ -115,14 +115,14 @@ "zod": "^4.4.3" }, "overrides": { - "tar": "^7.5.15" + "tar": "^7.5.21" }, "resolutions": { - "tar": "^7.5.15" + "tar": "^7.5.21" }, "pnpm": { "overrides": { - "tar": "^7.5.15" + "tar": "^7.5.21" } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index db96d94..5059d83 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + tar: ^7.5.15 + importers: .: @@ -1355,11 +1358,6 @@ packages: resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} engines: {node: '>= 18'} - mkdirp@3.0.1: - resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} - engines: {node: '>=10'} - hasBin: true - mlly@1.8.2: resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} @@ -1631,10 +1629,9 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true - tar@7.2.0: - resolution: {integrity: sha512-hctwP0Nb4AB60bj8WQgRYaMOuJYRAPMGiQUAotms5igN8ppfQM+IvjQ5HcKu1MaZh2Wy2KWVTe563Yj8dfc14w==} + tar@7.5.22: + resolution: {integrity: sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==} engines: {node: '>=18'} - deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} @@ -2913,8 +2910,6 @@ snapshots: dependencies: minipass: 7.1.3 - mkdirp@3.0.1: {} - mlly@1.8.2: dependencies: acorn: 8.16.0 @@ -3036,7 +3031,7 @@ snapshots: execa: 9.6.1 get-port: 7.2.0 http-proxy: 1.18.1(debug@4.4.3) - tar: 7.2.0 + tar: 7.5.22 transitivePeerDependencies: - debug @@ -3170,13 +3165,12 @@ snapshots: tinyglobby: 0.2.16 ts-interface-checker: 0.1.13 - tar@7.2.0: + tar@7.5.22: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 minipass: 7.1.3 minizlib: 3.1.0 - mkdirp: 3.0.1 yallist: 5.0.0 term-size@2.2.1: {} diff --git a/src/utils/tests/download-file.test.ts b/src/utils/tests/download-file.test.ts index 08e5623..b43ac37 100644 --- a/src/utils/tests/download-file.test.ts +++ b/src/utils/tests/download-file.test.ts @@ -136,8 +136,8 @@ describe("downloadFile", () => { // Verify the in-flight request was aborted const fetchMock = global.fetch as unknown as ReturnType; - const { signal } = fetchMock.mock.calls[0][1] as { signal: AbortSignal }; - expect(signal.aborted).toBe(true); + const fetchOptions = fetchMock.mock.calls[0]?.[1] as { signal: AbortSignal }; + expect(fetchOptions.signal.aborted).toBe(true); consoleErrorSpy.mockRestore(); }); @@ -181,7 +181,9 @@ describe("downloadFile", () => { await expect(downloadFile({ url, destination })).rejects.toThrow(); - expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining("❌ Download failed: HTTP 502 Bad Gateway")); + expect(consoleErrorSpy).toHaveBeenCalledWith( + expect.stringContaining("❌ Download failed: HTTP 502 Bad Gateway"), + ); expect(consoleErrorSpy).not.toHaveBeenCalledWith(expect.stringContaining("\n")); consoleErrorSpy.mockRestore(); From ab9580b94a54cc358705ff374b7565a1ffac9111 Mon Sep 17 00:00:00 2001 From: Ugwuanyi TobeChukwu <39131739+amaify@users.noreply.github.com> Date: Thu, 6 Aug 2026 13:53:42 +0100 Subject: [PATCH 5/5] Run changeset --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22afc5f..a4bc74e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # @tobelabs/chainwright +## 0.10.13 + +### Patch Changes + +- [CLI] - Enhance error handling in downloadFile function. + ## 0.10.12 ### Patch Changes diff --git a/package.json b/package.json index 18bdbf3..4d492db 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chainwright", - "version": "0.10.12", + "version": "0.10.13", "description": "Playwright Web3 wallet testing framework for end-to-end dApp automation with MetaMask, Phantom, Solflare, Petra, Meteor, and Keplr", "type": "module", "license": "MIT",