javascriptipfsjs-ipfs

How to create a directory and add files to ipfs using js-ipfs with pure javascript only


The only answers I can find in my research cover uploading multiple files from a directory on a PC. That is not what I'm trying to do. I'm trying to create a directory in ipfs and then add new files to that directory using js-ipfs with pure javascript only, generally one file at a time.

I conceptually understand that a directory in ipfs is simply another file. But I don't understand how to create that directory (file) and add other files to it for later retrieval, particularly with js-ipfs and pure javascript code.

I am implicitly not using node.js, therefore neither react, angular or vue either.

This works for a single file with no directory on ipfs:

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/ipfs/dist/index.min.js"></script>
</head>
<script>
    document.addEventListener('DOMContentLoaded', async () => {
        const nodeId = 'ipfs-' + Math.random()
        const node = await Ipfs.create({ repo: nodeId })
        console.log("Your node: " + nodeId)
        window.node = node
        const status = node.isOnline() ? 'online' : 'offline'
        console.log(`Node status: ${status}`)
        async function addFile () {
            for await (const { cid } of node.add('Some file content!')) {
                console.log('successfully stored', cid)
                cidhash=cid.toBaseEncodedString()
                console.log(cidhash)
            }
        }
        addFile()
    })
</script>
<body>
</body>
</html>

How to make this work to create a directory and add a file to it initially, then add another file to the created directory later (pseudocode-ish)?

  async function addFile () {
    for await (const { directory, filename } of node.add('/someDirectory/someFilename','Some file content!')) {
      console.log('successfully stored', directory, filename)             
      console.log(directory, filename)
    }
  }

Solution

  • Reading through the js-ipfs documentation, I finally found the answer.

    To only create a directory:

    await ipfs.files.mkdir('/my/beautiful/directory')
    

    Full working example to create a directory path and add a file to it at the same time:

    <!DOCTYPE html>
    <html>
    <head>
      <script src="https://cdn.jsdelivr.net/npm/ipfs/dist/index.min.js"></script>
    </head>
    <script>
        document.addEventListener('DOMContentLoaded', async () => {
            const nodeId = 'ipfs-' + Math.random()
            const node = await Ipfs.create({ repo: nodeId })
            console.log("Your node: " + nodeId)
            window.node = node
            const status = node.isOnline() ? 'online' : 'offline'
            console.log(`Node status: ${status}`)
    
            //create a variable with the directory path '/my/beautiful/directory' 
            // and a file 'awesomesause.txt' with the content 'ABC' 
            var files = [{
                path: '/my/beautiful/directory/firstfile.txt',
                content: 'ABC'
            }]
    
            addFile(files) //add the first file       
    
            //update the 'files' variable to add another file to the directory path '/mybeautiful/directory' in ipfs
            files = [{
                path: '/my/beautiful/directory/secondfile.txt',
                content: 'DEF'
            }]
            
            addFile(files) //add the sectond file
    
            //function to add the files
            async function addFile (files) {
                for await (const result of node.add(files)) {
                    console.log(result)
                }
            }
        })
    </script>
    <body>
    </body>
    </html>
    

    Results:

    generating 2048-bit RSA keypair...
    js-ipfs_dirs_and_files.html:10 Your node: ipfs-[my random node ID]
    js-ipfs_dirs_and_files.html:13 Node status: online
    js-ipfs_dirs_and_files.html:35 
    Object
    cid: i {version: 0, codec: "dag-pb", multihash: Uint8Array(34), multibaseName: "base58btc", _buffer: Uint8Array(34), …}
    mode: 420
    mtime: undefined
    path: "my/beautiful/directory/firstfile.txt"
    size: 11
    __proto__: Object
    js-ipfs_dirs_and_files.html:35 
    Object
    cid: i {version: 0, codec: "dag-pb", multihash: Uint8Array(34), multibaseName: "base58btc", _buffer: Uint8Array(34), …}
    mode: 420
    mtime: undefined
    path: "my/beautiful/directory/secondfile.txt"
    size: 11
    __proto__: Object
    js-ipfs_dirs_and_files.html:35 
    Object
    cid: i {version: 0, codec: "dag-pb", multihash: Uint8Array(34), multibaseName: "base58btc", _buffer: Uint8Array(34), …}
    mode: 493
    mtime: undefined
    path: "my/beautiful/directory"
    size: 70
    __proto__: Object
    js-ipfs_dirs_and_files.html:35 
    Object
    cid: i {version: 0, codec: "dag-pb", multihash: Uint8Array(34), multibaseName: "base58btc", _buffer: Uint8Array(34), …}
    mode: 493
    mtime: undefined
    path: "my/beautiful/directory"
    size: 71
    __proto__: Object
    js-ipfs_dirs_and_files.html:35 
    Object
    cid: i {version: 0, codec: "dag-pb", multihash: Uint8Array(34), multibaseName: "base58btc", _buffer: Uint8Array(34), …}
    mode: 493
    mtime: undefined
    path: "my/beautiful"
    size: 125
    __proto__: Object
    js-ipfs_dirs_and_files.html:35 
    Object
    cid: i {version: 0, codec: "dag-pb", multihash: Uint8Array(34), multibaseName: "base58btc", _buffer: Uint8Array(34), …}
    mode: 493
    mtime: undefined
    path: "my/beautiful"
    size: 126
    __proto__: Object
    js-ipfs_dirs_and_files.html:35 
    Object
    cid: i {version: 0, codec: "dag-pb", multihash: Uint8Array(34), multibaseName: "base58btc", _buffer: Uint8Array(34), …}
    mode: 493
    mtime: undefined
    path: "my"
    size: 180
    __proto__: Object
    js-ipfs_dirs_and_files.html:35 
    Object
    cid: i {version: 0, codec: "dag-pb", multihash: Uint8Array(34), multibaseName: "base58btc", _buffer: Uint8Array(34), …}
    mode: 493
    mtime: undefined
    path: "my"
    size: 181
    __proto__: Object