import { fromByteArray } from 'base64-js'; function isString(arrayOrString: string | T[]): arrayOrString is string { return typeof (arrayOrString as string) === 'string'; } type MapGenericCallback = (value: T, index: number, array: T[]) => U; type MapStringCallback = (value: string, index: number, string: string) => U; function isMapStringCallback( arrayOrString: string | T[], callback: MapGenericCallback | MapStringCallback, ): callback is MapStringCallback { return !!callback && isString(arrayOrString); } // source - https://github.com/beatgammit/base64-js/blob/master/test/convert.js#L72 function map(array: T[], callback: MapGenericCallback): U[]; function map(string: string, callback: MapStringCallback): U[]; function map(arrayOrString: string | T[], callback: MapGenericCallback | MapStringCallback): U[] { const res = []; if (isString(arrayOrString) && isMapStringCallback(arrayOrString, callback)) { for (let k = 0, len = arrayOrString.length; k < len; k++) { if (arrayOrString.charAt(k)) { const kValue = arrayOrString.charAt(k); const mappedValue = callback(kValue, k, arrayOrString); res[k] = mappedValue; } } } else if (!isString(arrayOrString) && !isMapStringCallback(arrayOrString, callback)) { for (let k = 0, len = arrayOrString.length; k < len; k++) { if (k in arrayOrString) { const kValue = arrayOrString[k]; const mappedValue = callback(kValue, k, arrayOrString); res[k] = mappedValue; } } } return res; } export const encodeBase64 = (data: string): string => fromByteArray(new Uint8Array(map(data, (char) => char.charCodeAt(0)))); // base-64 decoder throws exception if encoded string is not padded by '=' to make string length // in multiples of 4. So gonna use our own method for this purpose to keep backwards compatibility // https://github.com/beatgammit/base64-js/blob/master/index.js#L26 export const decodeBase64 = (s: string): string => { const e = {} as { [key: string]: number }, w = String.fromCharCode, L = s.length; let i, b = 0, c, x, l = 0, a, r = ''; const A = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; for (i = 0; i < 64; i++) { e[A.charAt(i)] = i; } for (x = 0; x < L; x++) { c = e[s.charAt(x)]; b = (b << 6) + c; l += 6; while (l >= 8) { ((a = (b >>> (l -= 8)) & 0xff) || x < L - 2) && (r += w(a)); } } return r; };