Beta 7 with some repo names changed.
This commit is contained in:
1 parent
0f7b40cca7
commit
963c19493a
3408 files changed
+462217
-15516
No files matched your search
+52
@@ -0,0 +1,52 @@
|
||||
'use strict'
|
||||
|
||||
const mh = require('multihashes')
|
||||
const { Buffer } = require('buffer')
|
||||
var CIDUtil = {
|
||||
/**
|
||||
* Test if the given input is a valid CID object.
|
||||
* Returns an error message if it is not.
|
||||
* Returns undefined if it is a valid CID.
|
||||
*
|
||||
* @param {any} other
|
||||
* @returns {string}
|
||||
*/
|
||||
checkCIDComponents: function (other) {
|
||||
if (other == null) {
|
||||
return 'null values are not valid CIDs'
|
||||
}
|
||||
|
||||
if (!(other.version === 0 || other.version === 1)) {
|
||||
return 'Invalid version, must be a number equal to 1 or 0'
|
||||
}
|
||||
|
||||
if (typeof other.codec !== 'string') {
|
||||
return 'codec must be string'
|
||||
}
|
||||
|
||||
if (other.version === 0) {
|
||||
if (other.codec !== 'dag-pb') {
|
||||
return "codec must be 'dag-pb' for CIDv0"
|
||||
}
|
||||
if (other.multibaseName !== 'base58btc') {
|
||||
return "multibaseName must be 'base58btc' for CIDv0"
|
||||
}
|
||||
}
|
||||
|
||||
if (!Buffer.isBuffer(other.multihash)) {
|
||||
return 'multihash must be a Buffer'
|
||||
}
|
||||
|
||||
try {
|
||||
mh.validate(other.multihash)
|
||||
} catch (err) {
|
||||
let errorMsg = err.message
|
||||
if (!errorMsg) { // Just in case mh.validate() throws an error with empty error message
|
||||
errorMsg = 'Multihash validation failed'
|
||||
}
|
||||
return errorMsg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CIDUtil
|
||||
+308
@@ -0,0 +1,308 @@
|
||||
'use strict'
|
||||
|
||||
const { Buffer } = require('buffer')
|
||||
const mh = require('multihashes')
|
||||
const multibase = require('multibase')
|
||||
const multicodec = require('multicodec')
|
||||
const codecs = require('multicodec/src/base-table.json')
|
||||
const CIDUtil = require('./cid-util')
|
||||
const withIs = require('class-is')
|
||||
|
||||
/**
|
||||
* @typedef {Object} SerializedCID
|
||||
* @param {string} codec
|
||||
* @param {number} version
|
||||
* @param {Buffer} multihash
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test if the given input is a CID.
|
||||
* @function isCID
|
||||
* @memberof CID
|
||||
* @static
|
||||
* @param {any} other
|
||||
* @returns {bool}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing a CID `<mbase><version><mcodec><mhash>`
|
||||
* , as defined in [ipld/cid](https://github.com/multiformats/cid).
|
||||
* @class CID
|
||||
*/
|
||||
class CID {
|
||||
/**
|
||||
* Create a new CID.
|
||||
*
|
||||
* The algorithm for argument input is roughly:
|
||||
* ```
|
||||
* if (cid)
|
||||
* -> create a copy
|
||||
* else if (str)
|
||||
* if (1st char is on multibase table) -> CID String
|
||||
* else -> bs58 encoded multihash
|
||||
* else if (Buffer)
|
||||
* if (1st byte is 0 or 1) -> CID
|
||||
* else -> multihash
|
||||
* else if (Number)
|
||||
* -> construct CID by parts
|
||||
* ```
|
||||
*
|
||||
* @param {string|Buffer|CID} version
|
||||
* @param {string} [codec]
|
||||
* @param {Buffer} [multihash]
|
||||
* @param {string} [multibaseName]
|
||||
*
|
||||
* @example
|
||||
* new CID(<version>, <codec>, <multihash>, <multibaseName>)
|
||||
* new CID(<cidStr>)
|
||||
* new CID(<cid.buffer>)
|
||||
* new CID(<multihash>)
|
||||
* new CID(<bs58 encoded multihash>)
|
||||
* new CID(<cid>)
|
||||
*/
|
||||
constructor (version, codec, multihash, multibaseName) {
|
||||
if (_CID.isCID(version)) {
|
||||
// version is an exising CID instance
|
||||
const cid = version
|
||||
this.version = cid.version
|
||||
this.codec = cid.codec
|
||||
this.multihash = Buffer.from(cid.multihash)
|
||||
// Default guard for when a CID < 0.7 is passed with no multibaseName
|
||||
this.multibaseName = cid.multibaseName || (cid.version === 0 ? 'base58btc' : 'base32')
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof version === 'string') {
|
||||
// e.g. 'base32' or false
|
||||
const baseName = multibase.isEncoded(version)
|
||||
if (baseName) {
|
||||
// version is a CID String encoded with multibase, so v1
|
||||
const cid = multibase.decode(version)
|
||||
this.version = parseInt(cid.slice(0, 1).toString('hex'), 16)
|
||||
this.codec = multicodec.getCodec(cid.slice(1))
|
||||
this.multihash = multicodec.rmPrefix(cid.slice(1))
|
||||
this.multibaseName = baseName
|
||||
} else {
|
||||
// version is a base58btc string multihash, so v0
|
||||
this.version = 0
|
||||
this.codec = 'dag-pb'
|
||||
this.multihash = mh.fromB58String(version)
|
||||
this.multibaseName = 'base58btc'
|
||||
}
|
||||
CID.validateCID(this)
|
||||
Object.defineProperty(this, 'string', { value: version })
|
||||
return
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(version)) {
|
||||
const firstByte = version.slice(0, 1)
|
||||
const v = parseInt(firstByte.toString('hex'), 16)
|
||||
if (v === 1) {
|
||||
// version is a CID buffer
|
||||
const cid = version
|
||||
this.version = v
|
||||
this.codec = multicodec.getCodec(cid.slice(1))
|
||||
this.multihash = multicodec.rmPrefix(cid.slice(1))
|
||||
this.multibaseName = 'base32'
|
||||
} else {
|
||||
// version is a raw multihash buffer, so v0
|
||||
this.version = 0
|
||||
this.codec = 'dag-pb'
|
||||
this.multihash = version
|
||||
this.multibaseName = 'base58btc'
|
||||
}
|
||||
CID.validateCID(this)
|
||||
return
|
||||
}
|
||||
|
||||
// otherwise, assemble the CID from the parameters
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.version = version
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this.codec = codec
|
||||
|
||||
/**
|
||||
* @type {Buffer}
|
||||
*/
|
||||
this.multihash = multihash
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this.multibaseName = multibaseName || (version === 0 ? 'base58btc' : 'base32')
|
||||
|
||||
CID.validateCID(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* The CID as a `Buffer`
|
||||
*
|
||||
* @return {Buffer}
|
||||
* @readonly
|
||||
*
|
||||
* @memberOf CID
|
||||
*/
|
||||
get buffer () {
|
||||
let buffer = this._buffer
|
||||
|
||||
if (!buffer) {
|
||||
if (this.version === 0) {
|
||||
buffer = this.multihash
|
||||
} else if (this.version === 1) {
|
||||
buffer = Buffer.concat([
|
||||
Buffer.from('01', 'hex'),
|
||||
multicodec.getCodeVarint(this.codec),
|
||||
this.multihash
|
||||
])
|
||||
} else {
|
||||
throw new Error('unsupported version')
|
||||
}
|
||||
|
||||
// Cache this buffer so it doesn't have to be recreated
|
||||
Object.defineProperty(this, '_buffer', { value: buffer })
|
||||
}
|
||||
|
||||
return buffer
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prefix of the CID.
|
||||
*
|
||||
* @returns {Buffer}
|
||||
* @readonly
|
||||
*/
|
||||
get prefix () {
|
||||
return Buffer.concat([
|
||||
Buffer.from(`0${this.version}`, 'hex'),
|
||||
multicodec.getCodeVarint(this.codec),
|
||||
mh.prefix(this.multihash)
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to a CID of version `0`.
|
||||
*
|
||||
* @returns {CID}
|
||||
*/
|
||||
toV0 () {
|
||||
if (this.codec !== 'dag-pb') {
|
||||
throw new Error('Cannot convert a non dag-pb CID to CIDv0')
|
||||
}
|
||||
|
||||
const { name, length } = mh.decode(this.multihash)
|
||||
|
||||
if (name !== 'sha2-256') {
|
||||
throw new Error('Cannot convert non sha2-256 multihash CID to CIDv0')
|
||||
}
|
||||
|
||||
if (length !== 32) {
|
||||
throw new Error('Cannot convert non 32 byte multihash CID to CIDv0')
|
||||
}
|
||||
|
||||
return new _CID(0, this.codec, this.multihash)
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to a CID of version `1`.
|
||||
*
|
||||
* @returns {CID}
|
||||
*/
|
||||
toV1 () {
|
||||
return new _CID(1, this.codec, this.multihash)
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the CID into a string.
|
||||
*
|
||||
* @param {string} [base=this.multibaseName] - Base encoding to use.
|
||||
* @returns {string}
|
||||
*/
|
||||
toBaseEncodedString (base = this.multibaseName) {
|
||||
if (this.string && base === this.multibaseName) {
|
||||
return this.string
|
||||
}
|
||||
let str = null
|
||||
if (this.version === 0) {
|
||||
if (base !== 'base58btc') {
|
||||
throw new Error('not supported with CIDv0, to support different bases, please migrate the instance do CIDv1, you can do that through cid.toV1()')
|
||||
}
|
||||
str = mh.toB58String(this.multihash)
|
||||
} else if (this.version === 1) {
|
||||
str = multibase.encode(base, this.buffer).toString()
|
||||
} else {
|
||||
throw new Error('unsupported version')
|
||||
}
|
||||
if (base === this.multibaseName) {
|
||||
// cache the string value
|
||||
Object.defineProperty(this, 'string', { value: str })
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
/**
|
||||
* CID(QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n)
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
[Symbol.for('nodejs.util.inspect.custom')] () {
|
||||
return 'CID(' + this.toString() + ')'
|
||||
}
|
||||
|
||||
toString (base) {
|
||||
return this.toBaseEncodedString(base)
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize to a plain object.
|
||||
*
|
||||
* @returns {SerializedCID}
|
||||
*/
|
||||
toJSON () {
|
||||
return {
|
||||
codec: this.codec,
|
||||
version: this.version,
|
||||
hash: this.multihash
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare equality with another CID.
|
||||
*
|
||||
* @param {CID} other
|
||||
* @returns {bool}
|
||||
*/
|
||||
equals (other) {
|
||||
return this.codec === other.codec &&
|
||||
this.version === other.version &&
|
||||
this.multihash.equals(other.multihash)
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the given input is a valid CID object.
|
||||
* Throws if it is not.
|
||||
*
|
||||
* @param {any} other
|
||||
* @returns {void}
|
||||
*/
|
||||
static validateCID (other) {
|
||||
const errorMsg = CIDUtil.checkCIDComponents(other)
|
||||
if (errorMsg) {
|
||||
throw new Error(errorMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const _CID = withIs(CID, {
|
||||
className: 'CID',
|
||||
symbolName: '@ipld/js-cid/CID'
|
||||
})
|
||||
|
||||
_CID.codecs = codecs
|
||||
|
||||
module.exports = _CID
|
||||
Reference in new issue
Block a user