UNPKG

@waiting/base64

Version:

Base64 encoding/decoding in pure JS on both modern Browsers and Node.js. Also supports URL-safe base64

160 lines (153 loc) 4.55 kB
import { ErrMsg } from './config' export function parseEncodeInputString(input) { const ret = typeof input === 'string' ? input // tslint:disable-next-line: valid-typeof : (typeof input === 'number' || typeof input === 'bigint' ? input.toString() : null) if (ret === null) { throw new TypeError(ErrMsg.encodeInvalidParam) } return ret } export function parseDecodeInputBase64(base64) { if (typeof base64 !== 'string') { throw new TypeError(ErrMsg.notString) } else if (!validB64Chars(base64)) { throw new TypeError(ErrMsg.notValidB64String) } return base64 } export function parseTextEncoder(textEncoder) { if (typeof textEncoder === 'function') { return textEncoder } else if (typeof TextEncoder === 'function') { return TextEncoder } else { throw new TypeError(ErrMsg.textEncoderUndefined) } } export function parseTextDecoder(textDecoder) { if (typeof textDecoder === 'function') { return textDecoder } else if (typeof TextDecoder === 'function') { return TextDecoder } else { throw new TypeError(ErrMsg.textDecoderUndefined) } } /** Whether string contains valid base64 characters */ export function validB64Chars(input) { return /^[a-zA-Z0-9+/_-]+={0,2}$/.test(input) } /** Whether string contains valid URL-safe base64 characters */ export function validB64URLChars(input) { return /^[a-zA-Z0-9_-]+$/.test(input) } /** Validate input is valid base64 string or throw error */ export function validateB64(input) { const status = testB64(input) if (status !== true) { throw new Error(status) } } /** Validate input is valid URL-safe base64 string or throw error */ export function validateB64URL(input) { const status = testB64URL(input) if (status !== true) { throw new Error(status) } } /** Return true for valid base64 input, error message for invalid */ export function testB64(input) { if (typeof input !== 'string') { return ErrMsg.notString } else if (!validB64Chars(input)) { return ErrMsg.notValidB64String } else if (input.length < 4) { return ErrMsg.notValidB64Length } else if (input.length % 4 !== 0) { return ErrMsg.base64Invalidlength } return true } /** Return true for valid URL-safe base64 input, error message for invalid */ export function testB64URL(input) { if (typeof input !== 'string') { return ErrMsg.notString } else if (!validB64URLChars(input)) { return ErrMsg.notValidB64URLString } else if (input.length < 2) { // URL-safe at least 2 return ErrMsg.notValidB64URLLength } return true } /** Whether running in Node.js */ export function isRunningInNodejs() { // Buffer exists under karma testing /* istanbul ignore next */ return typeof process === 'object' && typeof Buffer === 'function' && typeof window === 'undefined' ? true : false } /** Whether input is instance of ArrayBuffer */ export function isArrayBuffer(buffer) { return buffer && buffer instanceof ArrayBuffer ? true : false } /** Whether input is instance of Uint8Array */ export function isUint8Array(buffer) { return ArrayBuffer.isView(buffer) && (buffer instanceof Uint8Array) ? true : false } /** * Convert base64 string to URL-safe base64 string. * Replace "+" to "-" and "/" to "_", and Remove "=" * * @see https://en.wikipedia.org/wiki/Base64#URL_applications */ export function b64toURLSafe(base64) { validateB64(base64) const pos = base64.indexOf('=') return pos > 0 ? base64.slice(0, pos).replace(/\+/g, '-').replace(/\//g, '_') : base64.replace(/\+/g, '-').replace(/\//g, '_') } /** * Convert URL-safe base64 string to base64 string. * Replace "-" to "+" and "_" to "/", and pad with "=" * * @see https://en.wikipedia.org/wiki/Base64#URL_applications */ export function b64fromURLSafe(base64) { validateB64URL(base64) const str = base64.replace(/-/g, '+').replace(/_/g, '/') return b64PadSuffix(str) } export function b64PadSuffix(input) { let num = 0 const mo = input.length % 4 switch (mo) { case 3: num = 1 break case 2: num = 2 break case 0: num = 0 break default: throw new Error(ErrMsg.notValidB64URLLength) } return input + '='.repeat(num) }