diff --git a/API.md b/API.md new file mode 100644 index 000000000..84044df8f --- /dev/null +++ b/API.md @@ -0,0 +1,695 @@ +# TOC + - [.add](#add) + - [.block](#block) + - [.cat](#cat) + - [.commands](#commands) + - [.config](#config) + - [.dht](#dht) + - [.diag](#diag) + - [.id](#id) + - [API](#api) + - [.log](#log) + - [.mount](#mount) + - [.name](#name) + - [.object](#object) + - [.pin](#pin) + - [.ping](#ping) + - [.refs](#refs) + - [.send](#send) + - [.swarm](#swarm) + - [.update (currently disabled, wait for IPFS 0.4.0)](#update-currently-disabled-wait-for-ipfs-040) + - [.version](#version) + + +# .add +add file. + +```js +done => { + if (!isNode) { + return done() + } + const file = new File({ + cwd: path.dirname(testfilePath), + base: path.dirname(testfilePath), + path: testfilePath, + contents: new Buffer(testfile) + }) + apiClients['a'].add + if (err) throw err + const added = res[0] != null ? res[0] : res + assert.equal(added.Hash, 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP') + assert.equal(added.Name, path.basename(testfilePath)) + done() + }) +``` + +add buffer. + +```js +done => { + let buf = new Buffer(testfile) + apiClients['a'].add + if (err) throw err + assert.equal(res.length, 1) + const added = res[0] + assert.equal(added.Hash, 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP') + done() + }) +``` + +add BIG buffer. + +```js +done => { + if (!isNode) { + return done() + } + apiClients['a'].add + if (err) throw err + assert.equal(res.length, 1) + const added = res[0] + assert.equal(added.Hash, 'Qme79tX2bViL26vNjPsF3DP1R9rMKMvnPYJiKTTKPrXJjq') + done() + }) +``` + +add path. + +```js +done => { + if (!isNode) { + return done() + } + apiClients['a'].add + if (err) throw err + const added = res[0] != null ? res[0] : res + assert.equal(added.Hash, 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP') + done() + }) +``` + +add a nested dir. + +```js +done => { + apiClients['a'].add + if (isNode) { + if (err) throw err + const added = res[res.length - 1] + assert.equal(added.Hash, 'QmSzLpCVbWnEm3XoTWnv6DT6Ju5BsVoLhzvxKXZeQ2cmdg') + done() + } else { + assert.equal(err.message, 'Recursive uploads are not supported in the browser') + done() + } + }) +``` + +add stream. + +```js +done => { + const stream = new Readable() + stream.push('Hello world') + stream.push(null) + apiClients['a'].add + if (err) throw err + const added = res[0] != null ? res[0] : res + assert.equal(added.Hash, 'QmNRCQWfgze6AbBCaT1rkrkV5tJ2aP4oTNPb5JZcXYywve') + done() + }) +``` + +add url. + +```js +done => { + const url = 'https://raw.githubusercontent.com/ipfs/js-ipfs-api/2a9cc63d7427353f2145af6b1a768a69e67c0588/README.md' + apiClients['a'].add + if (err) throw err + const added = res[0] != null ? res[0] : res + assert.equal(added.Hash, 'QmZmHgEX9baxUn3qMjsEXQzG6DyNcrVnwieQQTrpDdrFvt') + done() + }) +``` + + +# .block +block.put. + +```js +done => { + apiClients['a'].block.put + if (err) throw err + const store = res.Key + assert.equal(store, 'QmPv52ekjS75L4JmHpXVeuJ5uX2ecSfSZo88NSyxwA3rAQ') + done() + }) +``` + +block.get. + +```js +done => { + apiClients['a'].block.get + if (err) throw err + let buf = '' + res + .on('data', function (data) { buf += data }) + .on('end', function () { + assert.equal(buf, 'blorb') + done() + }) + }) +``` + + +# .cat +cat. + +```js +done => { + apiClients['a'].cat + if (err) { + throw err + } + let buf = '' + res + .on('error', err => { throw err }) + .on('data', data => buf += data) + .on('end', () => { + assert.equal(buf, testfile) + done() + }) + }) +``` + +cat BIG file. + +```js +done => { + if (!isNode) { + return done() + } + apiClients['a'].cat + if (err) { + throw err + } + testfileBig = require('fs').createReadStream(__dirname + '/../15mb.random', { bufferSize: 128 }) + // Do not blow out the memory of nodejs :) + streamEqual(res, testfileBig, (err, equal) => { + if (err) throw err + assert(equal) + done() + }) + }) +``` + + +# .commands +lists commands. + +```js +done => { + apiClients['a'].commands + if (err) { + throw err + } + assert(res) + done() + }) +``` + + +# .config +.config.{set, get}. + +```js +done => { + const confKey = 'arbitraryKey' + const confVal = 'arbitraryVal' + apiClients['a'].config.set + if (err) throw err + apiClients['a'].config.get(confKey, (err, res) => { + if (err) throw err + assert.equal(res.Value, confVal) + done() + }) + }) +``` + +.config.show. + +```js +done => { + apiClients['c'].config.show + if (err) { + throw err + } + assert(res) + done() + }) +``` + +.config.replace. + +```js +done => { + if (!isNode) { + return done() + } + apiClients['c'].config.replace + if (err) { + throw err + } + assert.equal(res, null) + done() + }) +``` + + +# .dht +returns an error when getting a non-existent key from the DHT. + +```js +done => { + apiClients['a'].dht.get + assert(err) + done() + }) +``` + +puts and gets a key value pair in the DHT. + +```js +done => { + apiClients['a'].dht.put + if (err) { + throw err + } + assert.equal(typeof res, 'object') + return done() + // non ipns or pk hashes fail to fetch, known bug + // bug: https://github.com/ipfs/go-ipfs/issues/1923#issuecomment-152932234 + // apiClients['a'].dht.get('scope', (err, value) => { + // console.log('->>', err, value) + // if (err) { + // throw err + // } + // assert.equal(value, 'interplanetary') + // done() + // }) + }) +``` + +.dht.findprovs. + +```js +done => { + apiClients['a'].dht.findprovs + if (err) { + throw err + } + assert.equal(typeof res, 'object') + assert(res) + done() + }) +``` + + +# .diag +.diag.net. + +```js +done => { + apiClients['a'].diag.net + if (err) { + throw err + } + assert(res) + done() + }) +``` + +.diag.sys. + +```js +done => { + apiClients['a'].diag.sys + if (err) { + throw err + } + assert(res) + assert(res.memory) + assert(res.diskinfo) + done() + }) +``` + + +# .id +id. + +```js +done => { + apiClients['a'].id + if (err) throw err + const id = res + assert(id.ID) + assert(id.PublicKey) + done() + }) +``` + + +# API +has the api object. + +```js +assert(apiClients['a']) +assert(apiClients['a'].id) +``` + + +# .log +.log.tail. + +```js +done => { + apiClients['a'].log.tail + if (err) { + throw err + } + res.once('data', obj => { + assert(obj) + assert.equal(typeof obj, 'object') + done() + }) + }) +``` + + +# .name +.name.publish. + +```js +done => { + apiClients['a'].name.publish + if (err) { + throw err + } + assert(res) + name = res + done() + }) +``` + +.name.resolve. + +```js +done => { + apiClients['a'].name.resolve + if (err) { + throw err + } + assert(res) + assert.deepEqual(res, { Path: '/ipfs/' + name.Value }) + done() + }) +``` + + +# .object +object.put. + +```js +done => { + apiClients['a'].object.put + if (err) throw err + const obj = res + assert.equal(obj.Hash, testObjectHash) + assert.equal(obj.Links.length, 0) + done() + }) +``` + +object.get. + +```js +done => { + apiClients['a'].object.get + if (err) { + throw err + } + const obj = res + assert.equal(obj.Data, 'testdata') + assert.equal(obj.Links.length, 0) + done() + }) +``` + +object.data. + +```js +done => { + apiClients['a'].object.data + if (err) throw err + let buf = '' + res + .on('error', err => { throw err }) + .on('data', data => buf += data) + .on('end', () => { + assert.equal(buf, 'testdata') + done() + }) + }) +``` + +object.stat. + +```js +done => { + apiClients['a'].object.stat + if (err) { + throw err + } + assert.deepEqual(res, { + Hash: 'QmPTkMuuL6PD8L2SwTwbcs1NPg14U8mRzerB1ZrrBrkSDD', + NumLinks: 0, + BlockSize: 10, + LinksSize: 2, + DataSize: 8, + CumulativeSize: 10 + }) + done() + }) +``` + +object.links. + +```js +done => { + apiClients['a'].object.links + if (err) { + throw err + } + assert.deepEqual(res, { + Hash: 'QmPTkMuuL6PD8L2SwTwbcs1NPg14U8mRzerB1ZrrBrkSDD', + Links: [] + }) + done() + }) +``` + +object.patch. + +```js +done => { + apiClients['a'].object.put + if (err) { + throw err + } + apiClients['a'].object.patch(testObjectHash, ['add-link', 'next', testPatchObjectHash], (err, res) => { + if (err) { + throw err + } + assert.deepEqual(res, { + Hash: 'QmZFdJ3CQsY4kkyQtjoUo8oAzsEs5BNguxBhp8sjQMpgkd', + Links: null + }) + apiClients['a'].object.get(res.Hash, (err, res2) => { + if (err) { + throw err + } + assert.deepEqual(res2, { + Data: 'testdata', + Links: [{ + Name: 'next', + Hash: 'QmWJDtdQWQSajQPx1UVAGWKaSGrHVWdjnrNhbooHP7LuF2', + Size: 15 + }] + }) + done() + }) + }) + }) +``` + + +# .pin +.pin.add. + +```js +done => { + apiClients['b'].pin.add + if (err) { + throw err + } + assert.equal(res.Pinned[0], 'Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP') + done() + }) +``` + +.pin.list. + +```js +done => { + apiClients['b'].pin.list + if (err) { + throw err + } + assert(res) + done() + }) +``` + +.pin.remove. + +```js +done => { + apiClients['b'].pin.remove + if (err) { + throw err + } + assert(res) + apiClients['b'].pin.list('direct', (err, res) => { + if (err) { + throw err + } + assert(res) + assert.equal(Object.keys(res.Keys).length, 0) + done() + }) + }) +``` + + +# .ping +ping another peer. + +```js +done => { + // TODO remove this when https://github.com/ipfs/js-ipfs-api/issues/135 is resolved + if (!isNode) { + return done() + } + apiClients['b'].id + if (err) { + throw err + } + apiClients['a'].ping(id.ID, (err, res) => { + if (err) { + throw err + } + assert(res) + assert(res.Success) + done() + }) + }) +``` + + +# .refs +refs. + +```js +done => { + if (!isNode) { + return done() + } + apiClients['a'].refs + if (err) { + throw err + } + const result = [{ + Ref: 'QmSzLpCVbWnEm3XoTWnv6DT6Ju5BsVoLhzvxKXZeQ2cmdg QmcUYKmQxmTcFom4R4UZP7FWeQzgJkwcFn51XrvsMy7PE9 add.js', + Err: '' + }, { + Ref: 'QmSzLpCVbWnEm3XoTWnv6DT6Ju5BsVoLhzvxKXZeQ2cmdg QmNeHxDfQfjVFyYj2iruvysLH9zpp78v3cu1s3BZq1j5hY cat.js', + Err: '' + }, { + Ref: 'QmSzLpCVbWnEm3XoTWnv6DT6Ju5BsVoLhzvxKXZeQ2cmdg QmTYFLz5vsdMpq4XXw1a1pSxujJc9Z5V3Aw1Qg64d849Zy files', + Err: '' + }, { + Ref: 'QmSzLpCVbWnEm3XoTWnv6DT6Ju5BsVoLhzvxKXZeQ2cmdg QmU7wetVaAqc3Meurif9hcYBHGvQmL5QdpPJYBoZizyTNL ipfs-add.js', + Err: '' + }, { + Ref: 'QmSzLpCVbWnEm3XoTWnv6DT6Ju5BsVoLhzvxKXZeQ2cmdg QmctZfSuegbi2TMFY2y3VQjxsH5JbRBu7XmiLfHNvshhio ls.js', + Err: '' + }, { + Ref: 'QmSzLpCVbWnEm3XoTWnv6DT6Ju5BsVoLhzvxKXZeQ2cmdg QmTDH2RXGn8XyDAo9YyfbZAUXwL1FCr44YJCN9HBZmL9Gj test-folder', + Err: '' + }, { + Ref: 'QmSzLpCVbWnEm3XoTWnv6DT6Ju5BsVoLhzvxKXZeQ2cmdg QmbkMNB6rwfYAxRvnG9CWJ6cKKHEdq2ZKTozyF5FQ7H8Rs version.js', + Err: '' + }] + assert.deepEqual(objs, result) + done() + }) +``` + + +# .send + +# .swarm +.swarm.peers. + +```js +done => { + apiClients['a'].swarm.peers + if (err) { + throw err + } + assert(res.Strings.length >= 2) + done() + }) +``` + +.swarm.connect. + +```js +done => { + // Done in the 'before' segment + done() +``` + + +# .update (currently disabled, wait for IPFS 0.4.0) + +# .version +checks the version. + +```js +done => { + apiClients['a'].version + if (err) { + throw err + } + assert(res) + assert(res.Version) + console.log(' - running against version', res.Version) + done() + }) +``` + diff --git a/README.md b/README.md index a62691578..d4996bce5 100644 --- a/README.md +++ b/README.md @@ -64,14 +64,18 @@ ipfs daemon ## API -### Level 1 Commands -Level 1 commands are simple commands +You can find more detailed documentation with examples at [API.md](/API.md). + + + + +----------------------------------------------------------------------------- + +### Previous API Docs #### add -Add a file (where file is any data) to ipfs returning the hash and name. The -name value will only be set if you are actually sending a file. A single or -array of files can be used. +Add a file (where file is any data) to ipfs returning the hash and name. The name value will only be set if you are actually sending a file. A single or array of files can be used. **Usage** ```javascript @@ -84,8 +88,7 @@ ipfs.add(files, function(err, res) { }) }) ``` -`files` can be a mixed array of filenames or buffers of data. A single value is -also acceptable. +`files` can be a mixed array of filenames or buffers of data. A single value is also acceptable. Example ```js @@ -185,9 +188,6 @@ curl "http://localhost:5001/api/v0/ls?arg=&stream-channels=true" **commands** -### Level 2 Commands -Level 2 commands are simply named spaced wrapped commands - #### Config #### Update diff --git a/examples/add.js b/examples/add.js deleted file mode 100644 index be3fdedd4..000000000 --- a/examples/add.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict' - -var ipfs = require('../src')('localhost', 5001) - -var f1 = 'Hello' -var f2 = 'World' - -ipfs.add([new Buffer(f1), new Buffer(f2)], function (err, res) { - if (err || !res) return console.log(err) - - for (var i = 0; i < res.length; i++) { - console.log(res[i]) - } -}) - -ipfs.add(['./files/hello.txt', './files/ipfs.txt'], function (err, res) { - if (err || !res) return console.log(err) - - for (var i = 0; i < res.length; i++) { - console.log(res[i]) - } -}) diff --git a/examples/cat.js b/examples/cat.js deleted file mode 100644 index d24aa5a2d..000000000 --- a/examples/cat.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict' - -var ipfs = require('../src')('localhost', 5001) - -var hash = [ - 'QmdFyxZXsFiP4csgfM5uPu99AvFiKH62CSPDw5TP92nr7w', - 'QmY9cxiHqTFoWamkQVkpmmqzBrY3hCBEL2XNu3NtX74Fuu' -] - -ipfs.cat(hash, function (err, res) { - if (err || !res) return console.log(err) - - if (res.readable) { - res.pipe(process.stdout) - } else { - console.log(res) - } -}) diff --git a/examples/files/hello.txt b/examples/files/hello.txt deleted file mode 100644 index e965047ad..000000000 --- a/examples/files/hello.txt +++ /dev/null @@ -1 +0,0 @@ -Hello diff --git a/examples/files/ipfs.txt b/examples/files/ipfs.txt deleted file mode 100644 index 95a311652..000000000 --- a/examples/files/ipfs.txt +++ /dev/null @@ -1 +0,0 @@ -IPFS diff --git a/examples/ipfs-add.js b/examples/ipfs-add.js deleted file mode 100755 index 572791db2..000000000 --- a/examples/ipfs-add.js +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env node - -var ipfs = require('../src')('localhost', 5001) -var files = process.argv.slice(2) - -ipfs.add(files, {recursive: true}, function (err, res) { - if (err || !res) return console.log(err) - - for (var i = 0; i < res.length; i++) { - console.log('added', res[i].Hash, res[i].Name) - } -}) diff --git a/examples/ls.js b/examples/ls.js deleted file mode 100644 index 6006e8696..000000000 --- a/examples/ls.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict' - -var ipfs = require('../src')('localhost', 5001) - -var hash = ['QmdbHK6gMiecyjjSoPnfJg6iKMF7v6E2NkoBgGpmyCoevh'] - -ipfs.ls(hash, function (err, res) { - if (err || !res) return console.log(err) - - res.Objects.forEach(function (node) { - console.log(node.Hash) - - console.log('Links [%d]', node.Links.length) - node.Links.forEach(function (link, i) { - console.log('[%d]', i, link) - }) - }) -}) diff --git a/examples/version.js b/examples/version.js deleted file mode 100644 index c69598525..000000000 --- a/examples/version.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict' - -var ipfs = require('../src')('localhost', 5001) - -ipfs.commands(function (err, res) { - if (err) throw err - console.log(res) -}) diff --git a/package.json b/package.json index 24aaf5f6d..b8c419e7e 100644 --- a/package.json +++ b/package.json @@ -38,9 +38,9 @@ "gulp-filter": "^3.0.1", "gulp-git": "^1.6.0", "gulp-load-plugins": "^1.0.0", - "gulp-mocha": "^2.1.3", "gulp-size": "^2.0.0", "gulp-tag-version": "^1.3.0", + "gulp-spawn-mocha": "^2.2.1", "gulp-util": "^3.0.7", "https-browserify": "0.0.1", "ipfsd-ctl": "^0.6.1", diff --git a/tasks/test.js b/tasks/test.js index 0c32dfb16..9fa4734cb 100644 --- a/tasks/test.js +++ b/tasks/test.js @@ -26,6 +26,15 @@ gulp.task('test:node', done => { ) }) +gulp.task('docs', done => { + runSequence( + 'daemons:start', + 'mocha:docs', + 'daemons:stop', + done + ) +}) + gulp.task('test:browser', done => { runSequence( 'daemons:start', @@ -39,10 +48,20 @@ gulp.task('mocha', () => { return gulp.src([ 'test/setup.js', 'test/**/*.spec.js' - ]) - .pipe($.mocha({ - timeout: config.webpack.dev.timeout - })) + ]).pipe($.spawnMocha({ + timeout: config.webpack.dev.timeout + })) +}) + +gulp.task('mocha:docs', function () { + return gulp.src([ + 'test/setup.js', + 'test/**/*.spec.js' + ]).pipe($.spawnMocha({ + timeout: config.webpack.dev.timeout, + reporter: 'markdown', + output: 'API.md' + })) }) gulp.task('karma', done => {