From 631d1eb641248da441aa78db6e1530d8e4a3e9a6 Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Tue, 4 Jun 2024 15:28:42 -0400 Subject: [PATCH 1/7] Use `@metamask/superstruct`, set `moduleResolution` to `NodeNext` (#185) ## Explanation As part of our OKR for upgrading TypeScript to v5.0+ (Q2 2024 O3KR4), we are updating our core dependencies to generate builds and type declarations for both CJS and ESM. - Replaces all references to `superstruct` with ESM-compatible `@metamask/superstruct` fork. - Set TypeScript `module`, `moduleResolution` options to `NodeNext`. ## References - Closes: https://github.com/MetaMask/utils/issues/186 - Blocks: https://github.com/MetaMask/core/issues/3651 - Blocked by: https://github.com/MetaMask/superstruct/pull/20 ## Changelog ```md ### Changed - **BREAKING:** Replace dependency `superstruct` `^1.0.3` with ESM-compatible `@metamask/superstruct` `^3.0.0` ([#185](https://github.com/MetaMask/utils/pull/185)). - Bump devDependency `typescript` from `~4.8.4` to `~5.0.4` ([#185](https://github.com/MetaMask/utils/pull/185)). ``` --------- Co-authored-by: Elliot Winkler --- package.json | 2 +- src/assert.test.ts | 8 ++++---- src/assert.ts | 4 ++-- src/base64.test.ts | 2 +- src/base64.ts | 4 ++-- src/caip-types.ts | 4 ++-- src/checksum.test.ts | 2 +- src/checksum.ts | 2 +- src/coercers.ts | 4 ++-- src/hex.ts | 4 ++-- src/json.test-d.ts | 4 ++-- src/json.test.ts | 8 ++++---- src/json.ts | 9 +++++---- src/versions.ts | 4 ++-- tsconfig.json | 4 ++-- yarn.lock | 16 ++++++++-------- 16 files changed, 41 insertions(+), 40 deletions(-) diff --git a/package.json b/package.json index 9552a176d..3851b7126 100644 --- a/package.json +++ b/package.json @@ -62,13 +62,13 @@ }, "dependencies": { "@ethereumjs/tx": "^4.2.0", + "@metamask/superstruct": "^3.0.0", "@noble/hashes": "^1.3.1", "@scure/base": "^1.1.3", "@types/debug": "^4.1.7", "debug": "^4.3.4", "pony-cause": "^2.1.10", "semver": "^7.5.4", - "superstruct": "^1.0.3", "uuid": "^9.0.1" }, "devDependencies": { diff --git a/src/assert.test.ts b/src/assert.test.ts index 200da4818..787288e9c 100644 --- a/src/assert.test.ts +++ b/src/assert.test.ts @@ -1,4 +1,4 @@ -import { string, assert as superstructAssert } from 'superstruct'; +import { string, assert as superstructAssert } from '@metamask/superstruct'; import { assert, @@ -7,8 +7,8 @@ import { assertStruct, } from './assert'; -jest.mock('superstruct', () => ({ - ...jest.requireActual('superstruct'), +jest.mock('@metamask/superstruct', () => ({ + ...jest.requireActual('@metamask/superstruct'), assert: jest.fn(), })); @@ -50,7 +50,7 @@ describe('assertExhaustive', () => { describe('assertStruct', () => { beforeEach(() => { - const actual = jest.requireActual('superstruct'); + const actual = jest.requireActual('@metamask/superstruct'); ( superstructAssert as jest.MockedFunction ).mockImplementation(actual.assert); diff --git a/src/assert.ts b/src/assert.ts index 5892ebbfc..e25516d5e 100644 --- a/src/assert.ts +++ b/src/assert.ts @@ -1,5 +1,5 @@ -import type { Struct } from 'superstruct'; -import { assert as assertSuperstruct } from 'superstruct'; +import type { Struct } from '@metamask/superstruct'; +import { assert as assertSuperstruct } from '@metamask/superstruct'; import { getErrorMessage } from './errors'; diff --git a/src/base64.test.ts b/src/base64.test.ts index 79522b4f2..8499e606c 100644 --- a/src/base64.test.ts +++ b/src/base64.test.ts @@ -1,4 +1,4 @@ -import { is, size, string } from 'superstruct'; +import { is, size, string } from '@metamask/superstruct'; import type { Base64Options } from './base64'; import { base64 } from './base64'; diff --git a/src/base64.ts b/src/base64.ts index 8106e5963..1f6f71d7e 100644 --- a/src/base64.ts +++ b/src/base64.ts @@ -1,5 +1,5 @@ -import type { Struct } from 'superstruct'; -import { pattern } from 'superstruct'; +import type { Struct } from '@metamask/superstruct'; +import { pattern } from '@metamask/superstruct'; import { assert } from './assert'; diff --git a/src/caip-types.ts b/src/caip-types.ts index 416babf46..e19639735 100644 --- a/src/caip-types.ts +++ b/src/caip-types.ts @@ -1,5 +1,5 @@ -import type { Infer } from 'superstruct'; -import { is, pattern, string } from 'superstruct'; +import type { Infer } from '@metamask/superstruct'; +import { is, pattern, string } from '@metamask/superstruct'; export const CAIP_CHAIN_ID_REGEX = /^(?[-a-z0-9]{3,8}):(?[-_a-zA-Z0-9]{1,32})$/u; diff --git a/src/checksum.test.ts b/src/checksum.test.ts index 28bfe63b3..4a5c90a37 100644 --- a/src/checksum.test.ts +++ b/src/checksum.test.ts @@ -1,4 +1,4 @@ -import { is } from 'superstruct'; +import { is } from '@metamask/superstruct'; import { ChecksumStruct } from './checksum'; diff --git a/src/checksum.ts b/src/checksum.ts index ffe6f92bb..fe42dfc36 100644 --- a/src/checksum.ts +++ b/src/checksum.ts @@ -1,4 +1,4 @@ -import { size, string } from 'superstruct'; +import { size, string } from '@metamask/superstruct'; import { base64 } from './base64'; diff --git a/src/coercers.ts b/src/coercers.ts index ce8d7c82f..6f02ac224 100644 --- a/src/coercers.ts +++ b/src/coercers.ts @@ -1,4 +1,4 @@ -import type { Infer } from 'superstruct'; +import type { Infer } from '@metamask/superstruct'; import { bigint, coerce, @@ -8,7 +8,7 @@ import { string, StructError, union, -} from 'superstruct'; +} from '@metamask/superstruct'; import { assert } from './assert'; import { bytesToHex, hexToBytes } from './bytes'; diff --git a/src/hex.ts b/src/hex.ts index 07a92103e..66dd6da6e 100644 --- a/src/hex.ts +++ b/src/hex.ts @@ -1,6 +1,6 @@ +import type { Struct } from '@metamask/superstruct'; +import { is, pattern, string } from '@metamask/superstruct'; import { keccak_256 as keccak256 } from '@noble/hashes/sha3'; -import type { Struct } from 'superstruct'; -import { is, pattern, string } from 'superstruct'; import { assert } from './assert'; import { bytesToHex } from './bytes'; diff --git a/src/json.test-d.ts b/src/json.test-d.ts index b25b780d3..e2066807b 100644 --- a/src/json.test-d.ts +++ b/src/json.test-d.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -import type { Infer } from 'superstruct'; -import { boolean, number, optional, string } from 'superstruct'; +import type { Infer } from '@metamask/superstruct'; +import { boolean, number, optional, string } from '@metamask/superstruct'; import { expectAssignable, expectNotAssignable } from 'tsd'; import type { Json } from '.'; diff --git a/src/json.test.ts b/src/json.test.ts index ab0325433..2b92d895c 100644 --- a/src/json.test.ts +++ b/src/json.test.ts @@ -8,7 +8,7 @@ import { max, number, optional, -} from 'superstruct'; +} from '@metamask/superstruct'; import { assert, @@ -46,8 +46,8 @@ import { JSON_VALIDATION_FIXTURES, } from './__fixtures__'; -jest.mock('superstruct', () => ({ - ...jest.requireActual('superstruct'), +jest.mock('@metamask/superstruct', () => ({ + ...jest.requireActual('@metamask/superstruct'), assert: jest.fn(), })); @@ -225,7 +225,7 @@ describe('exactOptional', () => { describe('json', () => { beforeEach(() => { - const actual = jest.requireActual('superstruct'); + const actual = jest.requireActual('@metamask/superstruct'); ( superstructAssert as jest.MockedFunction ).mockImplementation(actual.assert); diff --git a/src/json.ts b/src/json.ts index ff6a5dc8e..988114eea 100644 --- a/src/json.ts +++ b/src/json.ts @@ -1,4 +1,3 @@ -import type { Context, Infer } from 'superstruct'; import { any, array, @@ -19,12 +18,14 @@ import { union, unknown, Struct, -} from 'superstruct'; +} from '@metamask/superstruct'; import type { + Context, + Infer, ObjectSchema, - Optionalize, Simplify, -} from 'superstruct/dist/utils'; + Optionalize, +} from '@metamask/superstruct'; import type { AssertionErrorConstructor } from './assert'; import { assertStruct } from './assert'; diff --git a/src/versions.ts b/src/versions.ts index ad0bc2b2c..99ee6e75d 100644 --- a/src/versions.ts +++ b/src/versions.ts @@ -1,3 +1,5 @@ +import type { Struct } from '@metamask/superstruct'; +import { is, refine, string } from '@metamask/superstruct'; import { gt as gtSemver, gtr as gtrSemver, @@ -5,8 +7,6 @@ import { valid as validSemVerVersion, validRange as validSemVerRange, } from 'semver'; -import type { Struct } from 'superstruct'; -import { is, refine, string } from 'superstruct'; import { assertStruct } from './assert'; import type { Opaque } from './opaque'; diff --git a/tsconfig.json b/tsconfig.json index ffd391d27..01e09f861 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,8 +4,8 @@ "exactOptionalPropertyTypes": true, "forceConsistentCasingInFileNames": true, "lib": ["ES2020", "dom"], - "module": "CommonJS", - "moduleResolution": "node", + "module": "nodenext", + "moduleResolution": "nodenext", "noEmit": true, "noErrorTruncation": true, "noUncheckedIndexedAccess": true, diff --git a/yarn.lock b/yarn.lock index a48c43f3d..467dba608 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1054,6 +1054,13 @@ __metadata: languageName: node linkType: hard +"@metamask/superstruct@npm:^3.0.0": + version: 3.0.0 + resolution: "@metamask/superstruct@npm:3.0.0" + checksum: 667f8f2947186972516bb72b4ba215eaeede257c8beb0450583dd4c8b00c28729ff938267ca8804a3a351277fd627b8607cafeb71eb7045a2b6930639bb6a341 + languageName: node + linkType: hard + "@metamask/utils@workspace:.": version: 0.0.0-use.local resolution: "@metamask/utils@workspace:." @@ -1066,6 +1073,7 @@ __metadata: "@metamask/eslint-config-jest": ^12.0.0 "@metamask/eslint-config-nodejs": ^12.0.0 "@metamask/eslint-config-typescript": ^12.0.0 + "@metamask/superstruct": ^3.0.0 "@noble/hashes": ^1.3.1 "@scure/base": ^1.1.3 "@ts-bridge/cli": ^0.1.2 @@ -1095,7 +1103,6 @@ __metadata: prettier-plugin-packagejson: ^2.3.0 semver: ^7.5.4 stdio-mock: ^1.2.0 - superstruct: ^1.0.3 ts-jest: ^29.0.3 ts-node: ^10.7.0 tsd: ^0.29.0 @@ -6753,13 +6760,6 @@ __metadata: languageName: node linkType: hard -"superstruct@npm:^1.0.3": - version: 1.0.3 - resolution: "superstruct@npm:1.0.3" - checksum: 761790bb111e6e21ddd608299c252f3be35df543263a7ebbc004e840d01fcf8046794c274bcb351bdf3eae4600f79d317d085cdbb19ca05803a4361840cc9bb1 - languageName: node - linkType: hard - "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" From c72216b0303b3192dfa41023c6c88f939cde9054 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 13:47:05 -0400 Subject: [PATCH 2/7] 8.5.0 (#191) This is the release candidate for version 8.5.0. --------- Co-authored-by: github-actions Co-authored-by: Jongsun Suh --- CHANGELOG.md | 15 ++++++++++++++- package.json | 4 ++-- yarn.lock | 18 +++++++++--------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc04ef66c..93c82df1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [8.5.0] +### Changed +- Bump dependency `semver` from `^5.7.1` to `^7.6.0` ([#181](https://github.com/MetaMask/utils/pull/181)). + +### Fixed +- Replace dependency `superstruct` `^1.0.3` with ESM-compatible `@metamask/superstruct` `^3.0.0` ([#185](https://github.com/MetaMask/utils/pull/185)). + - This fixes the issue of this package being unusable by any TypeScript project that uses `Node16` or `NodeNext` as its `moduleResolution` option. +- Produce and export ESM-compatible TypeScript type declaration files in addition to CommonJS-compatible declaration files ([#182](https://github.com/MetaMask/utils/pull/182)) + - Previously, this package shipped with only one variant of type declaration files, and these files were only CommonJS-compatible, and the `exports` field in `package.json` linked to these files. This is an anti-pattern and was rightfully flagged by the ["Are the Types Wrong?"](https://arethetypeswrong.github.io/) tool as ["masquerading as CJS"](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/FalseCJS.md). All of the ATTW checks now pass. +- Remove chunk files ([#182](https://github.com/MetaMask/utils/pull/182)). + - Previously, the build tool we used to generate JavaScript files extracted common code to "chunk" files. While this was intended to make this package more tree-shakeable, it also made debugging more difficult for our development teams. These chunk files are no longer present. + ## [8.4.0] ### Added - Add `toCaipChainId` utility function ([#175](https://github.com/MetaMask/utils/pull/175)) @@ -223,7 +235,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial release -[Unreleased]: https://github.com/MetaMask/utils/compare/v8.4.0...HEAD +[Unreleased]: https://github.com/MetaMask/utils/compare/v8.5.0...HEAD +[8.5.0]: https://github.com/MetaMask/utils/compare/v8.4.0...v8.5.0 [8.4.0]: https://github.com/MetaMask/utils/compare/v8.3.0...v8.4.0 [8.3.0]: https://github.com/MetaMask/utils/compare/v8.2.1...v8.3.0 [8.2.1]: https://github.com/MetaMask/utils/compare/v8.2.0...v8.2.1 diff --git a/package.json b/package.json index 3851b7126..0853ac110 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/utils", - "version": "8.4.0", + "version": "8.5.0", "description": "Various JavaScript/TypeScript utilities of wide relevance to the MetaMask codebase", "homepage": "https://github.com/MetaMask/utils#readme", "bugs": { @@ -106,7 +106,7 @@ "ts-node": "^10.7.0", "tsd": "^0.29.0", "typedoc": "^0.23.15", - "typescript": "~4.8.4" + "typescript": "~5.0.4" }, "packageManager": "yarn@3.2.3", "engines": { diff --git a/yarn.lock b/yarn.lock index 467dba608..d0419cca1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1107,7 +1107,7 @@ __metadata: ts-node: ^10.7.0 tsd: ^0.29.0 typedoc: ^0.23.15 - typescript: ~4.8.4 + typescript: ~5.0.4 uuid: ^9.0.1 languageName: unknown linkType: soft @@ -7125,23 +7125,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:~4.8.4": - version: 4.8.4 - resolution: "typescript@npm:4.8.4" +"typescript@npm:~5.0.4": + version: 5.0.4 + resolution: "typescript@npm:5.0.4" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 3e4f061658e0c8f36c820802fa809e0fd812b85687a9a2f5430bc3d0368e37d1c9605c3ce9b39df9a05af2ece67b1d844f9f6ea8ff42819f13bcb80f85629af0 + checksum: 82b94da3f4604a8946da585f7d6c3025fff8410779e5bde2855ab130d05e4fd08938b9e593b6ebed165bda6ad9292b230984f10952cf82f0a0ca07bbeaa08172 languageName: node linkType: hard -"typescript@patch:typescript@~4.8.4#~builtin": - version: 4.8.4 - resolution: "typescript@patch:typescript@npm%3A4.8.4#~builtin::version=4.8.4&hash=a1c5e5" +"typescript@patch:typescript@~5.0.4#~builtin": + version: 5.0.4 + resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin::version=5.0.4&hash=a1c5e5" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 563a0ef47abae6df27a9a3ab38f75fc681f633ccf1a3502b1108e252e187787893de689220f4544aaf95a371a4eb3141e4a337deb9895de5ac3c1ca76430e5f0 + checksum: 6a1fe9a77bb9c5176ead919cc4a1499ee63e46b4e05bf667079f11bf3a8f7887f135aa72460a4c3b016e6e6bb65a822cb8689a6d86cbfe92d22cc9f501f09213 languageName: node linkType: hard From 6000435b2db84d48149a1d0938e8c7f22dc24c82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 11:18:55 +0200 Subject: [PATCH 3/7] Bump `braces` from `3.0.2` to `3.0.3` (#192) Bumps the npm_and_yarn group with 1 update in the / directory: [braces](https://github.com/micromatch/braces). Updates `braces` from 3.0.2 to 3.0.3
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=braces&package-manager=npm_and_yarn&previous-version=3.0.2&new-version=3.0.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/MetaMask/utils/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/yarn.lock b/yarn.lock index d0419cca1..6942ff1ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2190,11 +2190,11 @@ __metadata: linkType: hard "braces@npm:^3.0.2": - version: 3.0.2 - resolution: "braces@npm:3.0.2" + version: 3.0.3 + resolution: "braces@npm:3.0.3" dependencies: - fill-range: ^7.0.1 - checksum: e2a8e769a863f3d4ee887b5fe21f63193a891c68b612ddb4b68d82d1b5f3ff9073af066c343e9867a393fe4c2555dcb33e89b937195feb9c1613d259edfcd459 + fill-range: ^7.1.1 + checksum: b95aa0b3bd909f6cd1720ffcf031aeaf46154dd88b4da01f9a1d3f7ea866a79eba76a6d01cbc3c422b2ee5cdc39a4f02491058d5df0d7bf6e6a162a832df1f69 languageName: node linkType: hard @@ -3464,12 +3464,12 @@ __metadata: languageName: node linkType: hard -"fill-range@npm:^7.0.1": - version: 7.0.1 - resolution: "fill-range@npm:7.0.1" +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" dependencies: to-regex-range: ^5.0.1 - checksum: cc283f4e65b504259e64fd969bcf4def4eb08d85565e906b7d36516e87819db52029a76b6363d0f02d0d532f0033c9603b9e2d943d56ee3b0d4f7ad3328ff917 + checksum: b4abfbca3839a3d55e4ae5ec62e131e2e356bf4859ce8480c64c4876100f4df292a63e5bb1618e1d7460282ca2b305653064f01654474aa35c68000980f17798 languageName: node linkType: hard From 369e5b26e9ef9ccf461bf2449e234b6750208164 Mon Sep 17 00:00:00 2001 From: Elliot Winkler Date: Thu, 27 Jun 2024 09:14:30 -0600 Subject: [PATCH 4/7] Ensure functions that should return Hex, do (#193) Some functions that return hex strings satisfying the `Hex` type return a `string` type instead. This makes it slightly inconvenient to use these functions in conjunction with others, and it is common in practice to use a type assertion as a workaround. This commit rectifies this issue by assigning these functions proper return types: - `getChecksumAddress` - `numberToHex` - `bigIntToHex` As such this change is **breaking**. --- src/hex.ts | 2 +- src/number.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hex.ts b/src/hex.ts index 66dd6da6e..46bdbf648 100644 --- a/src/hex.ts +++ b/src/hex.ts @@ -87,7 +87,7 @@ export function isValidHexAddress(possibleAddress: Hex) { * @returns The address encoded according to ERC-55. * @see https://eips.ethereum.org/EIPS/eip-55 */ -export function getChecksumAddress(address: Hex) { +export function getChecksumAddress(address: Hex): Hex { assert(is(address, HexChecksumAddressStruct), 'Invalid hex address.'); const unPrefixed = remove0x(address.toLowerCase()); const unPrefixedHash = remove0x(bytesToHex(keccak256(unPrefixed))); diff --git a/src/number.ts b/src/number.ts index c485e1053..70e4ae935 100644 --- a/src/number.ts +++ b/src/number.ts @@ -1,4 +1,5 @@ import { assert } from './assert'; +import type { Hex } from './hex'; import { add0x, assertIsHexString } from './hex'; /** @@ -18,7 +19,7 @@ import { add0x, assertIsHexString } from './hex'; * @returns The hexadecimal string, with the "0x"-prefix. * @throws If the number is not a non-negative safe integer. */ -export const numberToHex = (value: number): string => { +export const numberToHex = (value: number): Hex => { assert(typeof value === 'number', 'Value must be a number.'); assert(value >= 0, 'Value must be a non-negative number.'); assert( @@ -45,7 +46,7 @@ export const numberToHex = (value: number): string => { * @returns The hexadecimal string, with the "0x"-prefix. * @throws If the `bigint` is not a non-negative integer. */ -export const bigIntToHex = (value: bigint): string => { +export const bigIntToHex = (value: bigint): Hex => { assert(typeof value === 'bigint', 'Value must be a bigint.'); assert(value >= 0, 'Value must be a non-negative bigint.'); From 5a66cb82dc199d0a54a1a9f3e938850702c8eccb Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Thu, 27 Jun 2024 10:59:08 -0700 Subject: [PATCH 5/7] Bump `@metamask/superstruct` from `^3.0.0` to `^3.1.0` (#194) - Closes #186 --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 0853ac110..c05813974 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ }, "dependencies": { "@ethereumjs/tx": "^4.2.0", - "@metamask/superstruct": "^3.0.0", + "@metamask/superstruct": "^3.1.0", "@noble/hashes": "^1.3.1", "@scure/base": "^1.1.3", "@types/debug": "^4.1.7", diff --git a/yarn.lock b/yarn.lock index 6942ff1ba..9b3b3105c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1054,10 +1054,10 @@ __metadata: languageName: node linkType: hard -"@metamask/superstruct@npm:^3.0.0": - version: 3.0.0 - resolution: "@metamask/superstruct@npm:3.0.0" - checksum: 667f8f2947186972516bb72b4ba215eaeede257c8beb0450583dd4c8b00c28729ff938267ca8804a3a351277fd627b8607cafeb71eb7045a2b6930639bb6a341 +"@metamask/superstruct@npm:^3.1.0": + version: 3.1.0 + resolution: "@metamask/superstruct@npm:3.1.0" + checksum: 00e4d0c0aae8b25ccc1885c1db0bb4ed1590010570140c255e4deee3bf8a10c859c8fce5e475b4ae09c8a56316207af87585b91f7f5a5c028d668ccd111f19e3 languageName: node linkType: hard @@ -1073,7 +1073,7 @@ __metadata: "@metamask/eslint-config-jest": ^12.0.0 "@metamask/eslint-config-nodejs": ^12.0.0 "@metamask/eslint-config-typescript": ^12.0.0 - "@metamask/superstruct": ^3.0.0 + "@metamask/superstruct": ^3.1.0 "@noble/hashes": ^1.3.1 "@scure/base": ^1.1.3 "@ts-bridge/cli": ^0.1.2 From 654f9cf4c2f64a5c83a4e9a42264bf0382409570 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:42:24 -0400 Subject: [PATCH 6/7] 9.0.0 (#196) This is the release candidate for version 9.0.0. --------- Co-authored-by: github-actions Co-authored-by: Jongsun Suh --- CHANGELOG.md | 15 ++++++++++++++- package.json | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93c82df1e..3542a5fde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [9.0.0] +### Changed +- **BREAKING:** The return types of functions `getChecksumAddress`, `numberToHex`, `bigIntToHex` are narrowed from `string` to `Hex` ([#193](https://github.com/MetaMask/utils/pull/193)) + +### Fixed +- Bump `@metamask/superstruct` from `^3.0.0` to `^3.1.0` ([#194](https://github.com/MetaMask/utils/pull/194)) + - If `@metamask/utils` `<=8.5.0` is used with `@metamask/superstruct` `>=3.1.0` the following error may be encountered: + ```ts + error TS2742: The inferred type of 'ExampleType' cannot be named without a reference to '@metamask/utils/node_modules/@metamask/superstruct'. This is likely not portable. A type annotation is necessary. + ``` + This can be resolved by updating `@metamask/utils` to `>=9.0.0`. + ## [8.5.0] ### Changed - Bump dependency `semver` from `^5.7.1` to `^7.6.0` ([#181](https://github.com/MetaMask/utils/pull/181)). @@ -235,7 +247,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial release -[Unreleased]: https://github.com/MetaMask/utils/compare/v8.5.0...HEAD +[Unreleased]: https://github.com/MetaMask/utils/compare/v9.0.0...HEAD +[9.0.0]: https://github.com/MetaMask/utils/compare/v8.5.0...v9.0.0 [8.5.0]: https://github.com/MetaMask/utils/compare/v8.4.0...v8.5.0 [8.4.0]: https://github.com/MetaMask/utils/compare/v8.3.0...v8.4.0 [8.3.0]: https://github.com/MetaMask/utils/compare/v8.2.1...v8.3.0 diff --git a/package.json b/package.json index c05813974..c238c2e47 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/utils", - "version": "8.5.0", + "version": "9.0.0", "description": "Various JavaScript/TypeScript utilities of wide relevance to the MetaMask codebase", "homepage": "https://github.com/MetaMask/utils#readme", "bugs": { From b8f869d07b209e371aa8f0440888d9247d6d1cdd Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Fri, 12 Jul 2024 15:17:06 -0230 Subject: [PATCH 7/7] feat: Add PublicInterface type (#197) Add a type for deriving the "public interface" of a type, excluding private properties. Excluding private properties can be useful in making our classes more easily testable (types with private properties are more difficult to mock). --- src/misc.test-d.ts | 22 +++++++++++++++++++++- src/misc.ts | 9 +++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/misc.test-d.ts b/src/misc.test-d.ts index 42da5b00e..45623e834 100644 --- a/src/misc.test-d.ts +++ b/src/misc.test-d.ts @@ -1,8 +1,28 @@ import { expectAssignable, expectNotAssignable, expectType } from 'tsd'; -import type { RuntimeObject } from './misc'; +import type { PublicInterface, RuntimeObject } from './misc'; import { isObject, hasProperty, getKnownPropertyNames } from './misc'; +//============================================================================= +// PublicInterface +//============================================================================= + +class ClassWithPrivateProperties { + #foo: string; + + bar: string; + + constructor({ foo, bar }: { foo: string; bar: string }) { + this.#foo = foo; + this.bar = bar; + } +} + +// Private properties not required +expectAssignable>({ bar: 'bar' }); +// Public properties still required +expectNotAssignable>({}); + //============================================================================= // isObject //============================================================================= diff --git a/src/misc.ts b/src/misc.ts index 700d46760..ece1c11e0 100644 --- a/src/misc.ts +++ b/src/misc.ts @@ -17,6 +17,15 @@ export type Mutable< [Key in keyof Omit]: ObjectValue[Key]; }; +/** + * Get a type representing the public interface of the given type. The + * returned type will have all public properties, but will omit private + * properties. + * + * @template Interface - The interface to return a public representation of. + */ +export type PublicInterface = Pick; + /** * Useful for representing some value that _might_ be present and / or complete. *