graphql-relay
Version:
A library to help construct a graphql-js server supporting react-relay.
149 lines (147 loc) • 4.46 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', {
value: true,
});
exports.base64 = base64;
exports.unbase64 = unbase64;
function base64(input) {
const utf8Array = stringToUTF8Array(input);
let result = '';
const length = utf8Array.length;
const rest = length % 3;
for (let i = 0; i < length - rest; i += 3) {
const a = utf8Array[i];
const b = utf8Array[i + 1];
const c = utf8Array[i + 2];
result += first6Bits(a);
result += last2BitsAndFirst4Bits(a, b);
result += last4BitsAndFirst2Bits(b, c);
result += last6Bits(c);
}
if (rest === 1) {
const a = utf8Array[length - 1];
result += first6Bits(a) + last2BitsAndFirst4Bits(a, 0) + '==';
} else if (rest === 2) {
const a = utf8Array[length - 2];
const b = utf8Array[length - 1];
result +=
first6Bits(a) +
last2BitsAndFirst4Bits(a, b) +
last4BitsAndFirst2Bits(b, 0) +
'=';
}
return result;
}
function first6Bits(a) {
return toBase64Char((a >> 2) & 63);
}
function last2BitsAndFirst4Bits(a, b) {
return toBase64Char(((a << 4) | (b >> 4)) & 63);
}
function last4BitsAndFirst2Bits(b, c) {
return toBase64Char(((b << 2) | (c >> 6)) & 63);
}
function last6Bits(c) {
return toBase64Char(c & 63);
}
function unbase64(input) {
const utf8Array = [];
for (let i = 0; i < input.length; i += 4) {
const a = fromBase64Char(input[i]);
const b = fromBase64Char(input[i + 1]);
const c = fromBase64Char(input[i + 2]);
const d = fromBase64Char(input[i + 3]);
if (a === -1 || b === -1 || c === -1 || d === -1) {
/*
* Previously we used Node's API for parsing Base64 and following code
* Buffer.from(i, 'utf8').toString('base64')
* That silently ignored incorrect input and returned empty string instead
* Let's keep this behaviour for a time being and hopefully fix it in the future.
*/
return '';
}
const bitmap24 = (a << 18) | (b << 12) | (c << 6) | d;
utf8Array.push((bitmap24 >> 16) & 255);
utf8Array.push((bitmap24 >> 8) & 255);
utf8Array.push(bitmap24 & 255);
}
let paddingIndex = input.length - 1;
while (input[paddingIndex] === '=') {
--paddingIndex;
utf8Array.pop();
}
return utf8ArrayToString(utf8Array);
}
const b64CharacterSet =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
function toBase64Char(bitMap6) {
return b64CharacterSet.charAt(bitMap6);
}
function fromBase64Char(base64Char) {
if (base64Char === undefined) {
return -1;
}
return base64Char === '=' ? 0 : b64CharacterSet.indexOf(base64Char);
}
function stringToUTF8Array(input) {
const result = [];
for (const utfChar of input) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const code = utfChar.codePointAt(0);
if (code < 0x80) {
result.push(code);
} else if (code < 0x800) {
result.push(0xc0 | (code >> 6));
result.push(0x80 | (code & 0x3f));
} else if (code < 0x10000) {
result.push(0xe0 | (code >> 12));
result.push(0x80 | ((code >> 6) & 0x3f));
result.push(0x80 | (code & 0x3f));
} else {
result.push(0xf0 | (code >> 18));
result.push(0x80 | ((code >> 12) & 0x3f));
result.push(0x80 | ((code >> 6) & 0x3f));
result.push(0x80 | (code & 0x3f));
}
}
return result;
}
function utf8ArrayToString(input) {
let result = '';
for (let i = 0; i < input.length; ) {
const a = input[i++];
if ((a & 0x80) === 0) {
result += fromCodePoint(a);
continue;
}
const b = input[i++];
if ((a & 0xe0) === 0xc0) {
result += fromCodePoint(((a & 0x1f) << 6) | (b & 0x3f));
continue;
}
const c = input[i++];
if ((a & 0xf0) === 0xe0) {
result += fromCodePoint(
((a & 0x0f) << 12) | ((b & 0x3f) << 6) | (c & 0x3f),
);
continue;
}
const d = input[i++];
result += fromCodePoint(
((a & 0x07) << 18) | ((b & 0x3f) << 12) | ((c & 0x3f) << 6) | (d & 0x3f),
);
}
return result;
}
function fromCodePoint(code) {
if (code > 0x10ffff) {
/*
* Previously we used Node's API for parsing Base64 and following code
* Buffer.from(i, 'base64').toString('utf8')
* That silently ignored incorrect input and returned empty string instead
* Let's keep this behaviour for a time being and hopefully fix it in the future.
*/
return '';
}
return String.fromCodePoint(code);
}