10

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)
    }
  }
Dshiz
  • 3,099
  • 3
  • 26
  • 53
  • I thought it was not possible to add or read files using javascript – Thanveer Shah Jun 30 '20 at 00:38
  • @ThanveerShah ipfs is a distributed filesystem. You are correct that you cannot create a normal local file in browser JS. – Jared Smith Jun 30 '20 at 00:39
  • @JaredSmith, I'll surely look into this , thanks. Also this might be out of topic but is it possible to read a zip file from the project directory using this? – Thanveer Shah Jun 30 '20 at 00:41
  • 1
    @ThanveerShah no. – Jared Smith Jun 30 '20 at 00:41
  • @ThanveerShah There is a script source CDN available to bring Buffer to the browser, but it is very flakey (https://wzrd.in/standalone/buffer). Either way, that's not what I'm trying to do. I want to create a file with text content, but I want to put that file in a directory created on IPFS. I'm not trying to upload a local directory of files. – Dshiz Jun 30 '20 at 00:49
  • @Dshiz Thanks, I'll take a look, I am using JSZip in react and it works perfectly when I browse a zip file , it unzips and displays all the images inside it.But when I put the same zip file in my project directory and try to access it using the path , it doesnt work. – Thanveer Shah Jun 30 '20 at 00:52
  • @ThanveerShah I should say the script itself works, but the host is often down. Get it when the host responds and reference in your src folder directly. For me that doesn't work because I'm creating a single file application that runs serverless -- and without a web packager. – Dshiz Jun 30 '20 at 01:00
  • @Dshiz , I was finally able to read a zip file from directory path using JsZip-utils :D, also glad that you found the answer you were looking for, just accept your answer so it will help people too – Thanveer Shah Jun 30 '20 at 23:22

1 Answers1

4

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
Dshiz
  • 3,099
  • 3
  • 26
  • 53