This repository has been archived by the owner on Aug 24, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 24
/
index.js
148 lines (132 loc) · 3.95 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
* Implementation of the [multibase](https://github.com/multiformats/multibase) specification.
*
*/
'use strict'
const constants = require('./constants')
const { encodeText, decodeText, concat } = require('./util')
/** @typedef {import('./base')} Base */
/** @typedef {import("./types").BaseNameOrCode} BaseNameOrCode */
/** @typedef {import("./types").BaseCode} BaseCode */
/** @typedef {import("./types").BaseName} BaseName */
/**
* Create a new Uint8Array with the multibase varint+code.
*
* @param {BaseNameOrCode} nameOrCode - The multibase name or code number.
* @param {Uint8Array} buf - The data to be prefixed with multibase.
* @returns {Uint8Array}
* @throws {Error} Will throw if the encoding is not supported
*/
function multibase (nameOrCode, buf) {
if (!buf) {
throw new Error('requires an encoded Uint8Array')
}
const { name, codeBuf } = encoding(nameOrCode)
validEncode(name, buf)
return concat([codeBuf, buf], codeBuf.length + buf.length)
}
/**
* Encode data with the specified base and add the multibase prefix.
*
* @param {BaseNameOrCode} nameOrCode - The multibase name or code number.
* @param {Uint8Array} buf - The data to be encoded.
* @returns {Uint8Array}
* @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
*
* @param {Uint8Array|string} data
* @returns {Uint8Array}
* @throws {Error} Will throw if the encoding is not supported
*
*/
function decode (data) {
if (data instanceof Uint8Array) {
data = decodeText(data)
}
const prefix = data[0]
// Make all encodings case-insensitive except the ones that include upper and lower chars in the alphabet
if (['f', 'F', 'v', 'V', 't', 'T', 'b', 'B', 'c', 'C', 'h', 'k', 'K'].includes(prefix)) {
data = data.toLowerCase()
}
const enc = encoding(/** @type {BaseCode} */(data[0]))
return enc.decode(data.substring(1))
}
/**
* Is the given data multibase encoded?
*
* @param {Uint8Array|string} data
* @returns {false | string}
*/
function isEncoded (data) {
if (data instanceof Uint8Array) {
data = decodeText(data)
}
// Ensure bufOrString is a string
if (Object.prototype.toString.call(data) !== '[object String]') {
return false
}
try {
const enc = encoding(/** @type {BaseCode} */(data[0]))
return enc.name
} catch (err) {
return false
}
}
/**
* Validate encoded data
*
* @param {BaseNameOrCode} name
* @param {Uint8Array} buf
* @returns {void}
* @throws {Error} Will throw if the encoding is not supported
*/
function validEncode (name, buf) {
const enc = encoding(name)
enc.decode(decodeText(buf))
}
/**
* Get the encoding by name or code
*
* @param {BaseNameOrCode} nameOrCode
* @returns {Base}
* @throws {Error} Will throw if the encoding is not supported
*/
function encoding (nameOrCode) {
if (constants.names[/** @type {BaseName} */(nameOrCode)]) {
return constants.names[/** @type {BaseName} */(nameOrCode)]
} else if (constants.codes[/** @type {BaseCode} */(nameOrCode)]) {
return constants.codes[/** @type {BaseCode} */(nameOrCode)]
} else {
throw new Error(`Unsupported encoding: ${nameOrCode}`)
}
}
/**
* Get encoding from data
*
* @param {string|Uint8Array} data
* @returns {Base}
* @throws {Error} Will throw if the encoding is not supported
*/
function encodingFromData (data) {
if (data instanceof Uint8Array) {
data = decodeText(data)
}
return encoding(/** @type {BaseCode} */(data[0]))
}
exports = module.exports = multibase
exports.encode = encode
exports.decode = decode
exports.isEncoded = isEncoded
exports.encoding = encoding
exports.encodingFromData = encodingFromData
exports.names = Object.freeze(constants.names)
exports.codes = Object.freeze(constants.codes)