From 1c1a3ecdd73af245f8212ca57206f34fc50b0b1e Mon Sep 17 00:00:00 2001 From: "metamask-ci[bot]" <271559518+metamask-ci[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2026 21:08:56 +0000 Subject: [PATCH 1/3] fix(deps): update dependency cockatiel to v4 --- packages/base-data-service/package.json | 2 +- packages/controller-utils/package.json | 2 +- packages/core-backend/package.json | 2 +- packages/network-controller/package.json | 2 +- packages/shield-controller/package.json | 2 +- yarn.lock | 17 ++++++++++++----- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/packages/base-data-service/package.json b/packages/base-data-service/package.json index fbae551d80c..1bffcb2c09a 100644 --- a/packages/base-data-service/package.json +++ b/packages/base-data-service/package.json @@ -56,7 +56,7 @@ "@metamask/superstruct": "^3.4.1", "@metamask/utils": "^12.0.0", "@tanstack/query-core": "^5.62.16", - "cockatiel": "^3.1.2", + "cockatiel": "^4.0.0", "fast-deep-equal": "^3.1.3", "lodash-es": "^4.17.21" }, diff --git a/packages/controller-utils/package.json b/packages/controller-utils/package.json index 79e03b494fc..403a2cb0145 100644 --- a/packages/controller-utils/package.json +++ b/packages/controller-utils/package.json @@ -56,7 +56,7 @@ "@types/bn.js": "^5.2.0", "bignumber.js": "^9.1.2", "bn.js": "^5.2.5", - "cockatiel": "^3.1.2", + "cockatiel": "^4.0.0", "eth-ens-namehash": "^2.0.8", "fast-deep-equal": "^3.1.3", "lodash-es": "^4.17.21" diff --git a/packages/core-backend/package.json b/packages/core-backend/package.json index 79fd66afea4..2fbc9c126e4 100644 --- a/packages/core-backend/package.json +++ b/packages/core-backend/package.json @@ -59,7 +59,7 @@ "@metamask/utils": "^12.0.0", "@tanstack/query-core": "^5.62.16", "async-mutex": "^0.5.0", - "cockatiel": "^3.1.2", + "cockatiel": "^4.0.0", "uuid": "^11.1.1" }, "devDependencies": { diff --git a/packages/network-controller/package.json b/packages/network-controller/package.json index cfa1efc327f..ebd0f68ec12 100644 --- a/packages/network-controller/package.json +++ b/packages/network-controller/package.json @@ -82,7 +82,7 @@ "@types/lodash-es": "^4.17.12", "@types/node-fetch": "^2.6.12", "@typescript/native": "npm:typescript@^7.0.2", - "cockatiel": "^3.1.2", + "cockatiel": "^4.0.0", "deep-freeze-strict": "^1.1.1", "deepmerge": "^4.2.2", "jest": "^30.4.2", diff --git a/packages/shield-controller/package.json b/packages/shield-controller/package.json index 3e2f20db875..2781be05228 100644 --- a/packages/shield-controller/package.json +++ b/packages/shield-controller/package.json @@ -59,7 +59,7 @@ "@metamask/transaction-controller": "^70.1.0", "@metamask/utils": "^12.0.0", "@tanstack/query-core": "^5.62.16", - "cockatiel": "^3.1.2" + "cockatiel": "^4.0.0" }, "devDependencies": { "@babel/runtime": "^7.23.9", diff --git a/yarn.lock b/yarn.lock index 29194f6d549..a41e4d8c15b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6092,7 +6092,7 @@ __metadata: "@types/jest": "npm:^30.0.0" "@types/lodash-es": "npm:^4.17.12" "@typescript/native": "npm:typescript@^7.0.2" - cockatiel: "npm:^3.1.2" + cockatiel: "npm:^4.0.0" deepmerge: "npm:^4.2.2" fast-deep-equal: "npm:^3.1.3" jest: "npm:^30.4.2" @@ -6531,7 +6531,7 @@ __metadata: "@typescript/native": "npm:typescript@^7.0.2" bignumber.js: "npm:^9.1.2" bn.js: "npm:^5.2.5" - cockatiel: "npm:^3.1.2" + cockatiel: "npm:^4.0.0" deepmerge: "npm:^4.2.2" eth-ens-namehash: "npm:^2.0.8" fast-deep-equal: "npm:^3.1.3" @@ -6566,7 +6566,7 @@ __metadata: "@types/jest": "npm:^30.0.0" "@typescript/native": "npm:typescript@^7.0.2" async-mutex: "npm:^0.5.0" - cockatiel: "npm:^3.1.2" + cockatiel: "npm:^4.0.0" deepmerge: "npm:^4.2.2" jest: "npm:^30.4.2" jest-environment-jsdom: "npm:^30.4.1" @@ -8136,7 +8136,7 @@ __metadata: "@types/lodash-es": "npm:^4.17.12" "@types/node-fetch": "npm:^2.6.12" "@typescript/native": "npm:typescript@^7.0.2" - cockatiel: "npm:^3.1.2" + cockatiel: "npm:^4.0.0" deep-freeze-strict: "npm:^1.1.1" deepmerge: "npm:^4.2.2" fast-deep-equal: "npm:^3.1.3" @@ -8925,7 +8925,7 @@ __metadata: "@tanstack/query-core": "npm:^5.62.16" "@types/jest": "npm:^30.0.0" "@typescript/native": "npm:typescript@^7.0.2" - cockatiel: "npm:^3.1.2" + cockatiel: "npm:^4.0.0" deepmerge: "npm:^4.2.2" jest: "npm:^30.4.2" lodash-es: "npm:^4.17.21" @@ -15420,6 +15420,13 @@ __metadata: languageName: node linkType: hard +"cockatiel@npm:^4.0.0": + version: 4.0.0 + resolution: "cockatiel@npm:4.0.0" + checksum: 10/443bc255c19e2fb318296aff1a45c0db3c461d62f88ad4acb33db22db8880844eeab0c30c2e653d4efc5f7f0b3c2eec105514896d14c0aaa8f78dd33c790f2f9 + languageName: node + linkType: hard + "code-block-writer@npm:^13.0.3": version: 13.0.3 resolution: "code-block-writer@npm:13.0.3" From e22c756928e69c0dd2b0a4c2bb123b4581741783 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 22 Sep 2026 21:13:14 +0000 Subject: [PATCH 2/3] [dependabot skip] chore: add changelog entries for bumped dependencies --- packages/base-data-service/CHANGELOG.md | 1 + packages/controller-utils/CHANGELOG.md | 1 + packages/core-backend/CHANGELOG.md | 1 + packages/shield-controller/CHANGELOG.md | 1 + 4 files changed, 4 insertions(+) diff --git a/packages/base-data-service/CHANGELOG.md b/packages/base-data-service/CHANGELOG.md index 362cf9042f6..2900d5d54f2 100644 --- a/packages/base-data-service/CHANGELOG.md +++ b/packages/base-data-service/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Bump `@metamask/utils` from `^11.12.0` to `^12.0.0` ([#10192](https://github.com/MetaMask/core/pull/10192)) +- Bump `cockatiel` from `^3.1.2` to `^4.0.0` ([#10381](https://github.com/MetaMask/core/pull/10381)) ## [2.0.0] diff --git a/packages/controller-utils/CHANGELOG.md b/packages/controller-utils/CHANGELOG.md index c0ceb28a426..61e72be64cf 100644 --- a/packages/controller-utils/CHANGELOG.md +++ b/packages/controller-utils/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/utils` from `^11.12.0` to `^12.0.0` ([#10192](https://github.com/MetaMask/core/pull/10192)) - Bump `@types/bn.js` from `^5.1.5` to `^5.2.0` ([#10362](https://github.com/MetaMask/core/pull/10362)) - Bump `bn.js` from `^5.2.1` to `^5.2.5` ([#10362](https://github.com/MetaMask/core/pull/10362)) +- Bump `cockatiel` from `^3.1.2` to `^4.0.0` ([#10381](https://github.com/MetaMask/core/pull/10381)) ## [13.0.0] diff --git a/packages/core-backend/CHANGELOG.md b/packages/core-backend/CHANGELOG.md index bb5f133801d..53f83dc2631 100644 --- a/packages/core-backend/CHANGELOG.md +++ b/packages/core-backend/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `uuid` from `^9.0.1` to `^11.1.1` ([#10243](https://github.com/MetaMask/core/pull/10243)) - Bump `@metamask/profile-sync-controller` from `^32.1.1` to `^32.2.0` ([#10348](https://github.com/MetaMask/core/pull/10348)) +- Bump `cockatiel` from `^3.1.2` to `^4.0.0` ([#10381](https://github.com/MetaMask/core/pull/10381)) ## [11.0.0] diff --git a/packages/shield-controller/CHANGELOG.md b/packages/shield-controller/CHANGELOG.md index d797ec71c07..ef36fa1f0e1 100644 --- a/packages/shield-controller/CHANGELOG.md +++ b/packages/shield-controller/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/profile-sync-controller` from `^32.0.0` to `^32.2.0` ([#10184](https://github.com/MetaMask/core/pull/10184), [#10220](https://github.com/MetaMask/core/pull/10220), [#10348](https://github.com/MetaMask/core/pull/10348)) - Bump `@metamask/utils` from `^11.12.0` to `^12.0.0` ([#10192](https://github.com/MetaMask/core/pull/10192)) - Bump `@metamask/transaction-controller` from `^70.0.0` to `^70.1.0` ([#10242](https://github.com/MetaMask/core/pull/10242), [#10262](https://github.com/MetaMask/core/pull/10262)) +- Bump `cockatiel` from `^3.1.2` to `^4.0.0` ([#10381](https://github.com/MetaMask/core/pull/10381)) ## [7.0.1] From 7fc3f8c60feeb295e25b5aead2a01402bb05cb68 Mon Sep 17 00:00:00 2001 From: Salah-Eddine Saakoun Date: Sat, 26 Sep 2026 12:34:57 +0200 Subject: [PATCH 3/3] fix: make cockatiel v4 work on Node 22 and adopt its unknown error types --- eslint-suppressions.json | 2 +- jest.config.packages.cjs | 10 +++++++- package.json | 1 + packages/network-controller/CHANGELOG.md | 1 + .../src/rpc-service/rpc-service.ts | 24 +++++++++++++------ .../src/polling-with-policy.ts | 2 +- tests/cockatiel.cjs | 2 ++ tests/setupCockatiel.mjs | 17 +++++++++++++ yarn.lock | 1 + 9 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 tests/cockatiel.cjs create mode 100644 tests/setupCockatiel.mjs diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 5a72df11541..bc4f9378ecd 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -1284,7 +1284,7 @@ }, "packages/network-controller/src/rpc-service/rpc-service.ts": { "no-restricted-syntax": { - "count": 3 + "count": 2 } }, "packages/network-enablement-controller/src/NetworkEnablementController.ts": { diff --git a/jest.config.packages.cjs b/jest.config.packages.cjs index a96314934e2..5628861eb6a 100644 --- a/jest.config.packages.cjs +++ b/jest.config.packages.cjs @@ -99,6 +99,11 @@ module.exports = { // CommonJS, where the reverse is true, so they are pointed back at // `lodash`. The two have the same API. '^lodash-es$': require.resolve('lodash'), + // `cockatiel` is ESM only, and the tests compile to CommonJS, where it can + // only be `require`d on Node 24.9+. This shim hands out the namespace that + // `tests/setupCockatiel.mjs` loads through Jest's ESM loader instead, which + // also works on Node 22. + '^cockatiel$': '/../../tests/cockatiel.cjs', }, // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader @@ -149,7 +154,10 @@ module.exports = { setupFiles: ['../../tests/setup.ts'], // A list of paths to modules that run some code to configure or set up the testing framework before each test - setupFilesAfterEnv: ['../../tests/setupAfterEnv/index.ts'], + setupFilesAfterEnv: [ + '../../tests/setupCockatiel.mjs', + '../../tests/setupAfterEnv/index.ts', + ], // The number of seconds after which a test is considered as slow and reported as such in the results. // slowTestThreshold: 5, diff --git a/package.json b/package.json index 5d6290f15e0..64343f30dab 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "@yarnpkg/parsers": "^3.0.3", "@yarnpkg/types": "^4.0.0", "bats": "^1.13.0", + "cockatiel": "^4.0.0", "comment-json": "^4.5.1", "eslint": "^9.39.1", "eslint-config-prettier": "^9.1.0", diff --git a/packages/network-controller/CHANGELOG.md b/packages/network-controller/CHANGELOG.md index 4e30d884045..22902813fee 100644 --- a/packages/network-controller/CHANGELOG.md +++ b/packages/network-controller/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/utils` from `^11.12.0` to `^12.0.0` ([#10192](https://github.com/MetaMask/core/pull/10192)) - Bump `@metamask/analytics-controller` from `^3.0.0` to `^3.1.0` ([#10301](https://github.com/MetaMask/core/pull/10301)) - Bump `immer` from `^9.0.6` to `^9.0.21` ([#10331](https://github.com/MetaMask/core/pull/10331)) +- Bump `cockatiel` from `^3.1.2` to `^4.0.0` ([#10381](https://github.com/MetaMask/core/pull/10381)) ## [37.0.0] diff --git a/packages/network-controller/src/rpc-service/rpc-service.ts b/packages/network-controller/src/rpc-service/rpc-service.ts index 1eef498ba30..7633f5bc65c 100644 --- a/packages/network-controller/src/rpc-service/rpc-service.ts +++ b/packages/network-controller/src/rpc-service/rpc-service.ts @@ -9,7 +9,12 @@ import { handleWhen, } from '@metamask/controller-utils'; import { JsonRpcError, rpcErrors } from '@metamask/rpc-errors'; -import { Duration, getErrorMessage, hasProperty } from '@metamask/utils'; +import { + Duration, + getErrorMessage, + hasProperty, + isObject, +} from '@metamask/utils'; import type { Json, JsonRpcParams, @@ -231,9 +236,10 @@ export function isJsonParseError(error: unknown): boolean { * @param error - The error object to test. * @returns True if the error has an httpStatus of 502, 503, or 504. */ -export function isHttpServerError(error: Error): boolean { +export function isHttpServerError(error: unknown): boolean { return ( - 'httpStatus' in error && + isObject(error) && + hasProperty(error, 'httpStatus') && (error.httpStatus === 502 || error.httpStatus === 503 || error.httpStatus === 504) @@ -246,8 +252,10 @@ export function isHttpServerError(error: Error): boolean { * @param error - The error object to test. * @returns True if the error code is `ETIMEDOUT`. */ -export function isTimeoutError(error: Error): boolean { - return hasProperty(error, 'code') && error.code === 'ETIMEDOUT'; +export function isTimeoutError(error: unknown): boolean { + return ( + isObject(error) && hasProperty(error, 'code') && error.code === 'ETIMEDOUT' + ); } /** @@ -256,8 +264,10 @@ export function isTimeoutError(error: Error): boolean { * @param error - The error object to test. * @returns True if the error code is `ECONNRESET`. */ -export function isConnectionResetError(error: Error): boolean { - return hasProperty(error, 'code') && error.code === 'ECONNRESET'; +export function isConnectionResetError(error: unknown): boolean { + return ( + isObject(error) && hasProperty(error, 'code') && error.code === 'ECONNRESET' + ); } /** diff --git a/packages/shield-controller/src/polling-with-policy.ts b/packages/shield-controller/src/polling-with-policy.ts index 4372617eb38..ca1589ab052 100644 --- a/packages/shield-controller/src/polling-with-policy.ts +++ b/packages/shield-controller/src/polling-with-policy.ts @@ -69,7 +69,7 @@ export class PollingWithCockatielPolicy { this.#requestEntry.delete(requestId); } - #shouldRetry(error: Error): boolean { + #shouldRetry(error: unknown): boolean { if (error instanceof HttpError) { // Note: we don't retry on 5xx errors, only on 4xx errors. // but we won't retry on 400 coz it means that the request body is invalid. diff --git a/tests/cockatiel.cjs b/tests/cockatiel.cjs new file mode 100644 index 00000000000..84ae8fa7e5e --- /dev/null +++ b/tests/cockatiel.cjs @@ -0,0 +1,2 @@ +// See `tests/setupCockatiel.mjs`, which puts the namespace here. +module.exports = globalThis.__cockatiel__; diff --git a/tests/setupCockatiel.mjs b/tests/setupCockatiel.mjs new file mode 100644 index 00000000000..a666f7c3952 --- /dev/null +++ b/tests/setupCockatiel.mjs @@ -0,0 +1,17 @@ +// `cockatiel` is published as ESM only, and the package tests run as CommonJS. +// Jest can only `require()` an ES module on Node 24.9+, where the synchronous +// vm module APIs exist, so on Node 22 a plain `import` from a test file fails. +// +// Loading it here instead works on both, because this file is ESM and Jest +// loads it through its asynchronous ESM loader (enabled by +// `--experimental-vm-modules`). It stays inside the test sandbox, so fake +// timers and `instanceof` behave as they would for any other module. +// +// `tests/cockatiel.cjs` hands this namespace to anything that imports +// `cockatiel`; see the `moduleNameMapper` entry in `jest.config.packages.cjs`. +// +// The import below deliberately points at the real entry point rather than at +// `cockatiel`, which `moduleNameMapper` would send straight back here. +import * as cockatiel from 'cockatiel/dist/index.js'; + +globalThis.__cockatiel__ = cockatiel; diff --git a/yarn.lock b/yarn.lock index a41e4d8c15b..62c4b623db1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6611,6 +6611,7 @@ __metadata: "@yarnpkg/parsers": "npm:^3.0.3" "@yarnpkg/types": "npm:^4.0.0" bats: "npm:^1.13.0" + cockatiel: "npm:^4.0.0" comment-json: "npm:^4.5.1" eslint: "npm:^9.39.1" eslint-config-prettier: "npm:^9.1.0"