Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions src/cid.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,10 @@ export class CID {
/** @readonly */
this.bytes = bytes

// Circular reference
// flag to serializers that this is a CID and
// should be treated specially
/** @readonly */
this.asCID = this
this['/'] = bytes
}

// ArrayBufferView
Expand Down Expand Up @@ -229,24 +230,28 @@ export class CID {
* @returns {CID<Data, Format, Alg, Version>|null}
*/
static asCID (input) {
if (input == null) {
return null
}

const value = /** @type {any} */ (input)
if (value instanceof CID) {
// If value is instance of CID then we're all set.
return value
} else if (value != null && value.asCID === value) {
// If value isn't instance of this CID class but `this.asCID === this` is
// true it is CID instance coming from a different implementation (diff
// version or duplicate). In that case we rebase it to this `CID`
// implementation so caller is guaranteed to get instance with expected
// API.
} else if ((value['/'] != null && value['/'] === value.bytes) || value.asCID === value) {
// If value isn't instance of this CID class but `this.asCID === this` or
// `value['/'] === value.bytes` is true it is CID instance coming from a
// different implementation (diff version or duplicate). In that case we
// rebase it to this `CID` implementation so caller is guaranteed to get
// instance with expected API.
const { version, code, multihash, bytes } = value
return new CID(
version,
code,
/** @type {API.MultihashDigest<Alg>} */ (multihash),
bytes || encodeCID(version, code, multihash.bytes)
value['/'] ?? bytes ?? encodeCID(version, code, multihash.bytes)
)
} else if (value != null && value[cidSymbol] === true) {
} else if (value[cidSymbol] === true) {
// If value is a CID from older implementation that used to be tagged via
// symbol we still rebase it to the this `CID` implementation by
// delegating that to a constructor.
Expand Down
21 changes: 19 additions & 2 deletions src/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,25 @@ export const create = (code, digest) => CID.create(1, code, digest)
* @param {unknown|L} value
* @returns {value is L & CID}
*/
export const isLink = value =>
value != null && /** @type {{asCID: unknown}} */ (value).asCID === value
export const isLink = value => {
if (value == null) {
return false
}

const withSlash = /** @type {{'/'?: Uint8Array, bytes: Uint8Array}} */ (value)

if (withSlash['/'] != null && withSlash['/'] === withSlash.bytes) {
return true
}

const withAsCID = /** @type {{'asCID'?: unknown}} */ (value)

if (withAsCID.asCID === value) {
return true
}

return false
}

/**
* Takes cid in a string representation and creates an instance. If `base`
Expand Down
2 changes: 1 addition & 1 deletion test/test-cid.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ describe('CID', () => {
const cid2 = await new Promise((resolve) => {
receiver.onmessage = (event) => { resolve(event.data) }
})
assert.strictEqual(cid2.asCID, cid2)
assert.strictEqual(cid2['/'], cid2.bytes)
sender.close()
receiver.close()
})
Expand Down