UNPKG

multiformats

Version:

Interface for multihash, multicodec, multibase and CID

109 lines (105 loc) 2.93 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); class Encoder { constructor(name, prefix, baseEncode) { this.name = name; this.prefix = prefix; this.baseEncode = baseEncode; } encode(bytes) { if (bytes instanceof Uint8Array) { return `${ this.prefix }${ this.baseEncode(bytes) }`; } else { throw Error('Unknown type, must be binary type'); } } } class Decoder { constructor(name, prefix, baseDecode) { this.name = name; this.prefix = prefix; this.baseDecode = baseDecode; } decode(text) { if (typeof text === 'string') { switch (text[0]) { case this.prefix: { return this.baseDecode(text.slice(1)); } default: { throw Error(`Unable to decode multibase string ${ JSON.stringify(text) }, ${ this.name } decoder only supports inputs prefixed with ${ this.prefix }`); } } } else { throw Error('Can only multibase decode strings'); } } or(decoder) { const decoders = { [this.prefix]: this, ...decoder.decoders || { [decoder.prefix]: decoder } }; return new ComposedDecoder(decoders); } } class ComposedDecoder { constructor(decoders) { this.decoders = decoders; } or(decoder) { const other = decoder.decoders || { [decoder.prefix]: decoder }; return new ComposedDecoder({ ...this.decoders, ...other }); } decode(input) { const prefix = input[0]; const decoder = this.decoders[prefix]; if (decoder) { return decoder.decode(input); } else { throw RangeError(`Unable to decode multibase string ${ JSON.stringify(input) }, only inputs prefixed with ${ Object.keys(this.decoders) } are supported`); } } } class Codec { constructor(name, prefix, baseEncode, baseDecode) { this.name = name; this.prefix = prefix; this.baseEncode = baseEncode; this.baseDecode = baseDecode; this.encoder = new Encoder(name, prefix, baseEncode); this.decoder = new Decoder(name, prefix, baseDecode); } encode(input) { return this.encoder.encode(input); } decode(input) { return this.decoder.decode(input); } } const withAlphabet = ({name, prefix, encode, decode, alphabet}) => from({ name, prefix, encode: input => encode(input, alphabet), decode: input => { for (const char of input) { if (alphabet.indexOf(char) < 0) { throw new Error(`invalid ${ name } character`); } } return decode(input, alphabet); } }); const withSettings = ({name, prefix, settings, encode, decode}) => from({ name, prefix, encode: input => encode(input, settings), decode: input => decode(input, settings) }); const from = ({name, prefix, encode, decode}) => new Codec(name, prefix, encode, decode); exports.Codec = Codec; exports.from = from; exports.withAlphabet = withAlphabet; exports.withSettings = withSettings;