@fedify/fedify
Version:
An ActivityPub server framework
316 lines (308 loc) • 6.52 kB
JavaScript
import { Temporal } from "@js-temporal/polyfill";
import { URLPattern } from "urlpattern-polyfill";
globalThis.addEventListener = () => {};
import baseX from "@multiformats/base-x";
//#region runtime/multibase/util.ts
const textDecoder = new TextDecoder();
const decodeText = (bytes) => textDecoder.decode(bytes);
const textEncoder = new TextEncoder();
const encodeText = (text) => textEncoder.encode(text);
function concat(arrs, length) {
const output = new Uint8Array(length);
let offset = 0;
for (const arr of arrs) {
output.set(arr, offset);
offset += arr.length;
}
return output;
}
//#endregion
//#region runtime/multibase/base.ts
/**
* Class to encode/decode in the supported Bases
*/
var Base = class {
codeBuf;
codec;
constructor(name, code, factory, alphabet) {
this.name = name;
this.code = code;
this.alphabet = alphabet;
this.codeBuf = encodeText(this.code);
this.alphabet = alphabet;
this.codec = factory(alphabet);
}
encode(buf) {
return this.codec.encode(buf);
}
decode(string) {
for (const char of string) if (this.alphabet && this.alphabet.indexOf(char) < 0) throw new Error(`invalid character '${char}' in '${string}'`);
return this.codec.decode(string);
}
};
//#endregion
//#region runtime/multibase/rfc4648.ts
const decode$1 = (string, alphabet, bitsPerChar) => {
const codes$1 = {};
for (let i = 0; i < alphabet.length; ++i) codes$1[alphabet[i]] = i;
let end = string.length;
while (string[end - 1] === "=") --end;
const out = new Uint8Array(end * bitsPerChar / 8 | 0);
let bits = 0;
let buffer = 0;
let written = 0;
for (let i = 0; i < end; ++i) {
const value = codes$1[string[i]];
if (value === void 0) throw new SyntaxError("Invalid character " + string[i]);
buffer = buffer << bitsPerChar | value;
bits += bitsPerChar;
if (bits >= 8) {
bits -= 8;
out[written++] = 255 & buffer >> bits;
}
}
if (bits >= bitsPerChar || 255 & buffer << 8 - bits) throw new SyntaxError("Unexpected end of data");
return out;
};
const encode$1 = (data, alphabet, bitsPerChar) => {
const pad = alphabet[alphabet.length - 1] === "=";
const mask = (1 << bitsPerChar) - 1;
let out = "";
let bits = 0;
let buffer = 0;
for (let i = 0; i < data.length; ++i) {
buffer = buffer << 8 | data[i];
bits += 8;
while (bits > bitsPerChar) {
bits -= bitsPerChar;
out += alphabet[mask & buffer >> bits];
}
}
if (bits) out += alphabet[mask & buffer << bitsPerChar - bits];
if (pad) while (out.length * bitsPerChar & 7) out += "=";
return out;
};
/**
* RFC4648 Factory
*/
const rfc4648 = (bitsPerChar) => (alphabet) => {
return {
encode(input) {
return encode$1(input, alphabet, bitsPerChar);
},
decode(input) {
return decode$1(input, alphabet, bitsPerChar);
}
};
};
//#endregion
//#region runtime/multibase/constants.ts
const identity = () => {
return {
encode: decodeText,
decode: encodeText
};
};
/**
* name, code, implementation, alphabet
*
* @type {Array<[BaseName, BaseCode, CodecFactory, string]>}
*/
const constants = [
[
"identity",
"\0",
identity,
""
],
[
"base2",
"0",
rfc4648(1),
"01"
],
[
"base8",
"7",
rfc4648(3),
"01234567"
],
[
"base10",
"9",
baseX,
"0123456789"
],
[
"base16",
"f",
rfc4648(4),
"0123456789abcdef"
],
[
"base16upper",
"F",
rfc4648(4),
"0123456789ABCDEF"
],
[
"base32hex",
"v",
rfc4648(5),
"0123456789abcdefghijklmnopqrstuv"
],
[
"base32hexupper",
"V",
rfc4648(5),
"0123456789ABCDEFGHIJKLMNOPQRSTUV"
],
[
"base32hexpad",
"t",
rfc4648(5),
"0123456789abcdefghijklmnopqrstuv="
],
[
"base32hexpadupper",
"T",
rfc4648(5),
"0123456789ABCDEFGHIJKLMNOPQRSTUV="
],
[
"base32",
"b",
rfc4648(5),
"abcdefghijklmnopqrstuvwxyz234567"
],
[
"base32upper",
"B",
rfc4648(5),
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
],
[
"base32pad",
"c",
rfc4648(5),
"abcdefghijklmnopqrstuvwxyz234567="
],
[
"base32padupper",
"C",
rfc4648(5),
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567="
],
[
"base32z",
"h",
rfc4648(5),
"ybndrfg8ejkmcpqxot1uwisza345h769"
],
[
"base36",
"k",
baseX,
"0123456789abcdefghijklmnopqrstuvwxyz"
],
[
"base36upper",
"K",
baseX,
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
],
[
"base58btc",
"z",
baseX,
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
],
[
"base58flickr",
"Z",
baseX,
"123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
],
[
"base64",
"m",
rfc4648(6),
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
],
[
"base64pad",
"M",
rfc4648(6),
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
],
[
"base64url",
"u",
rfc4648(6),
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
],
[
"base64urlpad",
"U",
rfc4648(6),
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_="
]
];
const names = constants.reduce((prev, tupple) => {
prev[tupple[0]] = new Base(tupple[0], tupple[1], tupple[2], tupple[3]);
return prev;
}, {});
const codes = constants.reduce((prev, tupple) => {
prev[tupple[1]] = names[tupple[0]];
return prev;
}, {});
//#endregion
//#region runtime/multibase/index.ts
/**
* Encode data with the specified base and add the multibase prefix.
*
* @throws {Error} Will throw if the encoding is not supported
*/
function encode(nameOrCode, buf) {
const enc = encoding(nameOrCode);
const data = encodeText(enc.encode(buf));
return concat([enc.codeBuf, data], enc.codeBuf.length + data.length);
}
/**
* Takes a Uint8Array or string encoded with multibase header, decodes it and
* returns the decoded buffer
*
* @throws {Error} Will throw if the encoding is not supported
*/
function decode(data) {
if (data instanceof Uint8Array) data = decodeText(data);
const prefix = data[0];
if ([
"f",
"F",
"v",
"V",
"t",
"T",
"b",
"B",
"c",
"C",
"h",
"k",
"K"
].includes(prefix)) data = data.toLowerCase();
const enc = encoding(data[0]);
return enc.decode(data.substring(1));
}
/**
* Get the encoding by name or code
* @throws {Error} Will throw if the encoding is not supported
*/
function encoding(nameOrCode) {
if (Object.prototype.hasOwnProperty.call(names, nameOrCode)) return names[nameOrCode];
else if (Object.prototype.hasOwnProperty.call(codes, nameOrCode)) return codes[nameOrCode];
else throw new Error(`Unsupported encoding: ${nameOrCode}`);
}
//#endregion
export { codes, decode, decodeText, encode, encodeText, names };