feat(base64): export `atob` and `btoa`
ADD
packages/base64/atob.js
+import { decodeBase64 } from './decode.js';
+
+/**
+ * @param {string} encodedData a binary string containing base64-encoded data
+ * @returns {string} an ASCII string containing decoded data from `encodedData`
+ */
+export const atob = encodedData => {
+ const buf = decodeBase64(encodedData);
+ return String.fromCharCode(...buf);
+};

ADD
packages/base64/btoa.js
+import { encodeBase64 } from './encode.js';
+
+/**
+ * @param {string} stringToEncode the binary string to encode
+ * @returns {string} an ASCII string containing the base64 representation of `stringToEncode`
+ */
+export const btoa = stringToEncode => {
+ const bytes = stringToEncode.split('').map(char => {
+ const b = char.charCodeAt(0);
+ if (b > 0xff) {
+ throw new Error(`btoa: character out of range: ${char}`);
+ }
+ return b;
+ });
+ const buf = new Uint8Array(bytes);
+ return encodeBase64(buf);
+};

MODIFY
packages/base64/test/test-main.js
packages/base64/test/test-main.js
import test from 'ava';
-import { encodeBase64, decodeBase64 } from '../index.js';
+import { encodeBase64, decodeBase64, atob, btoa } from '../index.js';
function stringToBytes(string) {
const data = new Uint8Array(string.length);
@@ -26,6 +26,8 @@ test('bytes conversions', t => {
for (const [inp, outp] of insouts) {
t.is(encodeBase64(stringToBytes(inp)), outp, `${inp} encodes`);
t.is(bytesToString(decodeBase64(outp)), inp, `${outp} decodes`);
+ t.is(btoa(inp), outp, `${inp} encodes with btoa`);
+ t.is(atob(outp), inp, `${outp} decodes with atob`);
}
const inputs = [
'a',
@@ -41,5 +43,6 @@ test('bytes conversions', t => {
str,
`${str} round trips`,
);
+ t.is(atob(btoa(str)), str, `${str} round trips with atob(btoa)`);
}
});

feat(base64): export `atob` and `btoa`