Skip to content

Commit

Permalink
fix: convert cid before instanceof check (#9)
Browse files Browse the repository at this point in the history
The `CID` class can be loaded as an ESM or a CJS class which means
`instanceof` breaks since they are loaded from different places.

Run the passed `cid` through `CID.asCID` to convert it to whatever
we think the `CID` class is before the test.
  • Loading branch information
achingbrain authored Sep 2, 2021
1 parent d6a87fc commit b442488
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
node: [14, 15]
node: [14, 16]
fail-fast: true
steps:
- uses: actions/checkout@v2
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@
},
"homepage": "https://github.com/ipfs/js-blockstore-datastore-adapter#readme",
"devDependencies": {
"aegir": "^33.1.0",
"interface-blockstore-tests": "^1.0.0"
"aegir": "^35.0.2",
"interface-blockstore-tests": "^1.0.0",
"util": "^0.12.4"
},
"dependencies": {
"err-code": "^3.0.1",
Expand Down
47 changes: 35 additions & 12 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ const { BlockstoreAdapter } = require('interface-blockstore')
* @returns {Key}
*/
function cidToKey (cid) {
if (!(cid instanceof CID)) {
const c = CID.asCID(cid)

if (!(c instanceof CID)) {
throw errcode(new Error('Not a valid cid'), 'ERR_INVALID_CID')
}

return new Key('/' + base32.encode(cid.multihash.bytes).slice(1).toUpperCase(), false)
return new Key('/' + base32.encode(c.multihash.bytes).slice(1).toUpperCase(), false)
}

/**
Expand Down Expand Up @@ -50,32 +52,53 @@ function keyToCid (key) {
* @returns {string}
*/
function convertPrefix (prefix) {
let bytes
const firstChar = prefix.substring(0, 1)

if (firstChar === '/') {
return convertPrefix(prefix.substring(1))
}

/** @type {(input: string) => Uint8Array } */
let decoder

if (firstChar.toLowerCase() === 'b') {
// v1 cid prefix, remove version and codec bytes
bytes = base32.decode(prefix.toLowerCase()).subarray(2)
decoder = (input) => base32.decode(input.toLowerCase()).subarray(2)
} else if (firstChar.toLowerCase() === 'c') {
// v1 cid prefix, remove version and codec bytes
bytes = base32pad.decode(prefix.toLowerCase()).subarray(2)
decoder = (input) => base32pad.decode(input.toLowerCase()).subarray(2)
} else if (firstChar === 'z') {
// v1 cid
bytes = base58btc.decode(prefix).subarray(2)
decoder = (input) => base58btc.decode(input).subarray(2)
} else if (firstChar === 'Q') {
// v0 cid prefix
bytes = base58btc.decode('z' + prefix)
decoder = (input) => base58btc.decode('z' + input)
} else {
bytes = base32.decode('b' + prefix.toLowerCase()).subarray(2)
decoder = (input) => base32.decode('b' + input.toLowerCase()).subarray(2)
}

const str = base32.encode(bytes).substring(1).toUpperCase()
let bytes

// find the longest prefix that we can safely decode
for (let i = 1; i < prefix.length; i++) {
try {
bytes = decoder(prefix.substring(0, i))
} catch (err) {
if (err.message !== 'Unexpected end of data') {
throw err
}
}
}

let str = '/C'

if (bytes) {
// slice one character from the end of the string to ensure we don't end up
// with a padded value which could have a non-matching string at the end
str = `/${base32.encode(bytes).slice(1, -1).toUpperCase() || 'C'}`
}

return str || 'C'
return str
}

/**
Expand All @@ -85,7 +108,7 @@ function convertPrefix (prefix) {
function convertQuery (query) {
return {
...query,
prefix: query.prefix ? `/${convertPrefix(query.prefix)}` : undefined,
prefix: query.prefix ? convertPrefix(query.prefix) : undefined,
filters: query.filters
? query.filters.map(
filter => (pair) => {
Expand All @@ -110,7 +133,7 @@ function convertQuery (query) {
function convertKeyQuery (query) {
return {
...query,
prefix: query.prefix ? `/${convertPrefix(query.prefix)}` : undefined,
prefix: query.prefix ? convertPrefix(query.prefix) : undefined,
filters: query.filters
? query.filters.map(
filter => (key) => {
Expand Down

0 comments on commit b442488

Please sign in to comment.