base64.js 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import { toUint8Array } from "../bytes/index.js";
  2. import { encode as encodeBinary, decode as decodeBinary } from "./binary.js";
  3. const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
  4. function nodeBuffer() {
  5. return globalThis.Buffer;
  6. }
  7. export function normalize(text) {
  8. return text.replace(/[\n\r\t ]/g, "");
  9. }
  10. export function pad(text) {
  11. const remainder = text.length % 4;
  12. return remainder ? text + "=".repeat(4 - remainder) : text;
  13. }
  14. export function is(text) {
  15. if (typeof text !== "string") {
  16. return false;
  17. }
  18. const normalized = normalize(text);
  19. return normalized === "" || BASE64_REGEX.test(normalized);
  20. }
  21. export function encode(data, _options) {
  22. const bytes = toUint8Array(data);
  23. const buffer = nodeBuffer();
  24. if (buffer) {
  25. return buffer.from(bytes).toString("base64");
  26. }
  27. return btoa(encodeBinary(bytes));
  28. }
  29. export function decode(text, _options) {
  30. const normalized = normalize(text);
  31. if (!is(normalized)) {
  32. throw new TypeError("Input is not valid Base64 text");
  33. }
  34. const buffer = nodeBuffer();
  35. if (buffer) {
  36. return new Uint8Array(buffer.from(normalized, "base64"));
  37. }
  38. return decodeBinary(atob(normalized));
  39. }
  40. export const base64 = { encode, decode, is, normalize, pad };