UNPKG

@fedify/fedify

Version:

An ActivityPub server framework

316 lines (308 loc) • 6.52 kB
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 };