22import * as dagCbor from '@ipld/dag-cbor'
33import * as dagPb from '@ipld/dag-pb'
44import { UnixFS } from 'ipfs-unixfs'
5+ import { type CID } from 'multiformats/cid'
56import { toCidOrNull , getCodeOrNull , toCidStrOrNull } from './cid.js'
67import { isTruthy } from './helpers.js'
78import type { NormalizedDagPbNodeFormat , CodecType , NormalizedDagNode , NormalizedDagLink , dagNode } from '../types.js'
@@ -25,7 +26,7 @@ function isDagPbNode (node: dagNode | PBNode, cid: string): node is PBNode {
2526 * @param {string } cidStr - the cid string passed to `ipfs.dag.get`
2627 * @returns {import('../types').NormalizedDagNode }
2728 */
28- export default function normaliseDagNode ( node : dagNode | PBNode , cidStr : string ) : NormalizedDagNode {
29+ export function normaliseDagNode ( node : dagNode | PBNode , cidStr : string ) : NormalizedDagNode {
2930 const code = getCodeOrNull ( cidStr )
3031 if ( isDagPbNode ( node , cidStr ) ) {
3132 return normaliseDagPb ( node , cidStr , dagPb . code )
@@ -34,6 +35,7 @@ export default function normaliseDagNode (node: dagNode | PBNode, cidStr: string
3435 // @ts -expect-error - todo: resolve node type error
3536 return normaliseDagCbor ( node , cidStr , code ?? dagCbor . code )
3637}
38+ export default normaliseDagNode
3739
3840/**
3941 * Normalize links and add type info. Add unixfs info where available
@@ -120,18 +122,41 @@ export function normaliseDagCbor (data: NormalizedDagNode['data'], cid: string,
120122 }
121123}
122124
125+ type PlainObjectOrArray = Record < string , unknown > | unknown [ ] | string
126+
127+ function isPlainObjectOrArray ( obj : unknown ) : obj is PlainObjectOrArray {
128+ return (
129+ obj !== null &&
130+ typeof obj === 'object' &&
131+ ! ( obj instanceof ArrayBuffer ) &&
132+ ! ArrayBuffer . isView ( obj ) &&
133+ ! ( typeof obj === 'string' )
134+ )
135+ }
136+
137+ type DagCborNodeObject = Record < string , unknown > & { '/' : string | CID | null }
138+
139+ /**
140+ * This should be called after `isPlainObjectOrArray` to avoid type errors.
141+ */
142+ function isDagCborNodeObject ( obj : PlainObjectOrArray ) : obj is DagCborNodeObject {
143+ return Object . keys ( obj ) . length === 1 && ( obj as Record < string , unknown > ) [ '/' ] != null
144+ }
145+
123146/**
124147 * A valid IPLD link in a dag-cbor node is an object with single "/" property.
125148 */
126149export function findAndReplaceDagCborLinks ( obj : unknown , sourceCid : string , path : string = '' ) : NormalizedDagLink [ ] {
127- if ( obj == null || typeof obj !== 'object' || Buffer . isBuffer ( obj ) || typeof obj === 'string' ) {
150+ if ( ! isPlainObjectOrArray ( obj ) ) {
128151 return [ ]
129152 }
130153
131- // FIXME: remove as any cast
132- const cid = toCidOrNull ( obj as any )
133- if ( cid != null ) {
134- return [ { path, source : sourceCid , target : cid . toString ( ) , size : BigInt ( 0 ) , index : 0 } ]
154+ const cid = toCidOrNull ( obj )
155+ if ( typeof obj === 'string' || cid != null ) {
156+ if ( cid != null ) {
157+ return [ { path, source : sourceCid , target : cid . toString ( ) , size : BigInt ( 0 ) , index : 0 } ]
158+ }
159+ return [ ]
135160 }
136161
137162 if ( Array . isArray ( obj ) ) {
@@ -146,22 +171,19 @@ export function findAndReplaceDagCborLinks (obj: unknown, sourceCid: string, pat
146171 const keys = Object . keys ( obj )
147172
148173 // Support older `{ "/": Buffer } style links until all the IPLD formats are updated.
149- if ( keys . length === 1 && keys [ 0 ] === '/' ) {
150- // @ts -expect-error - todo: resolve this type error
174+ if ( isDagCborNodeObject ( obj ) ) {
151175 const targetCid = toCidOrNull ( obj [ '/' ] )
152176
153177 if ( targetCid == null ) return [ ]
154178
155179 const target = targetCid . toString ( )
156- // @ts -expect-error - todo: resolve this type error
157180 obj [ '/' ] = target
158181
159182 return [ { path, source : sourceCid , target, size : BigInt ( 0 ) , index : 0 } ]
160183 }
161184
162185 if ( keys . length > 0 ) {
163186 return keys
164- // @ts -expect-error - todo: resolve this type error
165187 . map ( key => findAndReplaceDagCborLinks ( obj [ key ] , sourceCid , isTruthy ( path ) ? `${ path } /${ key } ` : `${ key } ` ) )
166188 . reduce ( ( a , b ) => a . concat ( b ) )
167189 . filter ( a => Boolean ( a ) )
0 commit comments