From 1d698f12ce3b7581d5370aca2582077c1a6b20eb Mon Sep 17 00:00:00 2001 From: silverwind Date: Wed, 22 Jul 2026 21:37:11 +0200 Subject: [PATCH] chore: replace `uint8-to-base64` with native `btoa`/`atob` (#38579) Replace the single-use `uint8-to-base64` dependency with native `btoa`/`atob`. The implementation is exactly identical. --------- Signed-off-by: silverwind --- package.json | 1 - pnpm-lock.yaml | 8 -------- web_src/js/utils.test.ts | 6 ++++++ web_src/js/utils.ts | 7 ++----- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 56a798b0e65..7e13830f75c 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "tippy.js": "6.3.7", "toastify-js": "1.12.0", "tributejs": "5.1.3", - "uint8-to-base64": "0.2.1", "vanilla-colorful": "0.7.2", "vite": "8.1.4", "vite-string-plugin": "2.0.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 371b4de75a0..dbf8d6f6970 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -185,9 +185,6 @@ importers: tributejs: specifier: 5.1.3 version: 5.1.3 - uint8-to-base64: - specifier: 0.2.1 - version: 0.2.1 vanilla-colorful: specifier: 0.7.2 version: 0.7.2 @@ -4183,9 +4180,6 @@ packages: uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - uint8-to-base64@0.2.1: - resolution: {integrity: sha512-uO/84GaoDUfiAxpa8EksjVLE77A9Kc7ZTziN4zRpq4de9yLaLcZn3jx1/sVjyupsywcVX6RKWbqLe7gUNyzH+Q==} - unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -8902,8 +8896,6 @@ snapshots: uc.micro@2.1.0: {} - uint8-to-base64@0.2.1: {} - unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 diff --git a/web_src/js/utils.test.ts b/web_src/js/utils.test.ts index c72f55e773d..d1ab3caf72a 100644 --- a/web_src/js/utils.test.ts +++ b/web_src/js/utils.test.ts @@ -113,6 +113,12 @@ test('encodeURLEncodedBase64, decodeURLEncodedBase64', () => { expect(encodeURLEncodedBase64(uint8array('a'))).toEqual('YQ'); // standard base64: "YQ==" expect(new Uint8Array(decodeURLEncodedBase64('YQ'))).toEqual(uint8array('a')); expect(new Uint8Array(decodeURLEncodedBase64('YQ=='))).toEqual(uint8array('a')); + + expect(encodeURLEncodedBase64(uint8array('AA'))).toEqual('QUE'); // standard base64: "QUE=" + expect(new Uint8Array(decodeURLEncodedBase64('QUE'))).toEqual(uint8array('AA')); + + const allBytes = Uint8Array.from({length: 256}, (_, i) => i); + expect(new Uint8Array(decodeURLEncodedBase64(encodeURLEncodedBase64(allBytes)))).toEqual(allBytes); }); test('formatBytes', () => { diff --git a/web_src/js/utils.ts b/web_src/js/utils.ts index feeb4d3b6bd..34c4ed529e6 100644 --- a/web_src/js/utils.ts +++ b/web_src/js/utils.ts @@ -1,4 +1,3 @@ -import {decode, encode} from 'uint8-to-base64'; import type {IssuePageInfo, IssuePathInfo, RepoOwnerPathInfo} from './types.ts'; import {toggleElemClass, toggleElem} from './utils/dom.ts'; @@ -158,7 +157,7 @@ export function toAbsoluteUrl(url: string): string { /** Encode an Uint8Array into a URLEncoded base64 string. */ export function encodeURLEncodedBase64(uint8Array: Uint8Array): string { - return encode(uint8Array) + return btoa(Array.from(uint8Array, (byte) => String.fromCharCode(byte)).join('')) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=/g, ''); @@ -166,9 +165,7 @@ export function encodeURLEncodedBase64(uint8Array: Uint8Array): string { /** Decode a URLEncoded base64 to an Uint8Array. */ export function decodeURLEncodedBase64(base64url: string): Uint8Array { - return decode(base64url - .replace(/_/g, '/') - .replace(/-/g, '+')); + return Uint8Array.from(atob(base64url.replace(/_/g, '/').replace(/-/g, '+')), (ch) => ch.charCodeAt(0)); } const domParser = new DOMParser();