Commit a738ecf91d844ee886e94857a82177ab446113f1
add all module apis
Paul Frazee committed on 3/15/2016, 11:45:32 PMParent: 335022b47a65f2cc954c1ad739f3061a37f8bcd3
Files changed
markdown.js | ||
---|---|---|
@@ -37,8 +37,10 @@ | ||
37 | 37 | groupStart = i |
38 | 38 | } |
39 | 39 | } |
40 | 40 | }) |
41 | + if (groupStart) | |
42 | + groups.push([groupStart, groupStart+1]) | |
41 | 43 | return groups |
42 | 44 | } |
43 | 45 | |
44 | 46 | // replace <code> groupings with code-example nodes |
tmpl/apis/common/ssb-client.html.js | ||
---|---|---|
@@ -1,8 +1,0 @@ | ||
1 | -var md = require('../../../markdown') | |
2 | -var page = require('../../page.part') | |
3 | -module.exports = () => page({ | |
4 | - section: 'apis', | |
5 | - tab: 'apis-common', | |
6 | - path: '/apis/common/ssb-client.html', | |
7 | - content: md.doc(__dirname+'/ssb-client.md') | |
8 | -}) |
tmpl/apis/common/ssb-client.md | ||
---|---|---|
@@ -1,29 +1,0 @@ | ||
1 | -# ssb-client | |
2 | - | |
3 | -Scuttlebot client. | |
4 | - | |
5 | -```js | |
6 | -var ssbClient = require('ssb-client') | |
7 | - | |
8 | -// simplest usage, connect to localhost sbot | |
9 | -ssbClient(function (err, sbot) { | |
10 | - // ... | |
11 | -}) | |
12 | - | |
13 | -// configuration: | |
14 | -var keys = ssbKeys.loadOrCreateSync('./app-private.key') | |
15 | -ssbClient( | |
16 | - keys, // optional, defaults to ~/.ssb/secret | |
17 | - { | |
18 | - host: 'localhost', // optional, defaults to localhost | |
19 | - port: 8008, // optional, defaults to 8008 | |
20 | - key: keys.id // optional, defaults to keys.id | |
21 | - }, | |
22 | - function (err, sbot) { | |
23 | - // ... | |
24 | - } | |
25 | -) | |
26 | - | |
27 | -``` | |
28 | - | |
29 | -[View on Github](https://github.com/ssbc/ssb-client) |
tmpl/apis/common/ssb-feed.html.js | ||
---|---|---|
@@ -1,8 +1,0 @@ | ||
1 | -var md = require('../../../markdown') | |
2 | -var page = require('../../page.part') | |
3 | -module.exports = () => page({ | |
4 | - section: 'apis', | |
5 | - tab: 'apis-common', | |
6 | - path: '/apis/common/ssb-feed.html', | |
7 | - content: md.doc(__dirname+'/ssb-feed.md') | |
8 | -}) |
tmpl/apis/common/ssb-feed.md | ||
---|---|---|
@@ -1,34 +1,0 @@ | ||
1 | -# ssb-feed | |
2 | - | |
3 | -A publishing interface for scuttlebutt feeds. | |
4 | - | |
5 | -By default, Scuttlebot uses a "master" identity/feed, which `sbot.publish()` will append new messages to. If you want to manipulate additional feeds, you can load the keypair and then use this library to do so. | |
6 | - | |
7 | -## Example | |
8 | - | |
9 | -``` js | |
10 | - | |
11 | -var ssbFeed = require('ssb-feed') | |
12 | -var ssbClient = require('ssb-client') | |
13 | -var ssbKeys = require('ssb-keys') | |
14 | - | |
15 | -var alice = ssbKeys.generate() | |
16 | -ssbClient(function (err, sbot) { | |
17 | - var feed = ssbFeed(sbot, alice) | |
18 | - | |
19 | - // Post to alice's feed | |
20 | - feed.publish({ | |
21 | - type: 'post', | |
22 | - text: 'hello world, I am alice.' | |
23 | - }, function (err) { ... }) | |
24 | - | |
25 | - // Also available: | |
26 | - console.log(feed.id) | |
27 | - console.log(feed.keys) | |
28 | -}) | |
29 | -``` | |
30 | - | |
31 | -This example uses `ssb-client`, but, if you're embedding `scuttlebot` or the `secure-scuttlebutt` library into your process, you can use them locally. | |
32 | - | |
33 | -[View on Github](https://github.com/ssbc/ssb-feed) | |
34 | - |
tmpl/apis/common/ssb-keys.html.js | ||
---|---|---|
@@ -1,8 +1,0 @@ | ||
1 | -var md = require('../../../markdown') | |
2 | -var page = require('../../page.part') | |
3 | -module.exports = () => page({ | |
4 | - section: 'apis', | |
5 | - tab: 'apis-common', | |
6 | - path: '/apis/common/ssb-keys.html', | |
7 | - content: md.doc(__dirname+'/ssb-keys.md') | |
8 | -}) |
tmpl/apis/common/ssb-keys.md | ||
---|---|---|
@@ -1,78 +1,0 @@ | ||
1 | -# ssb-keys | |
2 | - | |
3 | -A common module for secure-scuttlebutt projects, provides an API to create or load elliptic-curve keypairs and to execute related crypto operations. | |
4 | - | |
5 | -```js | |
6 | -var ssbkeys = require('ssb-keys') | |
7 | - | |
8 | -ssbkeys.create(path, function(err, k) { | |
9 | - console.log(k) /* => { | |
10 | - id: String, | |
11 | - public: String, | |
12 | - private: String | |
13 | - }*/ | |
14 | -}) | |
15 | - | |
16 | -ssbkeys.load(path, function(err, k) { | |
17 | - console.log(k) /* => { | |
18 | - id: String, | |
19 | - public: String, | |
20 | - private: String | |
21 | - }*/ | |
22 | -}) | |
23 | - | |
24 | -var k = ssbkeys.createSync(path) | |
25 | -console.log(k) /* => { | |
26 | - id: String, | |
27 | - public: String, | |
28 | - private: String | |
29 | -}*/ | |
30 | - | |
31 | -var k = ssbkeys.loadSync(path) | |
32 | -console.log(k) /* => { | |
33 | - id: String, | |
34 | - public: String, | |
35 | - private: String | |
36 | -}*/ | |
37 | - | |
38 | -var k = ssbkeys.generate() | |
39 | -console.log(k) /* => { | |
40 | - id: String, | |
41 | - public: String, | |
42 | - private: String | |
43 | -}*/ | |
44 | - | |
45 | -var hash = ssbkeys.hash(new Buffer('deadbeef', 'hex')) | |
46 | -ssbkeys.isHash(hash) // => true | |
47 | - | |
48 | -var sig = ssbkeys.sign(k, hash) | |
49 | -ssbkeys.verify(k.public, sig, hash) // => true | |
50 | - | |
51 | -var secret = new Buffer('deadbeef', 'hex') | |
52 | -ssbkeys.hmac(secret, k.private) // => String | |
53 | - | |
54 | -var obj = ssbkeys.signObj(k, { foo: 'bar' }) | |
55 | -console.log(obj) /* => { | |
56 | - foo: 'bar', | |
57 | - signature: ... | |
58 | -} */ | |
59 | -ssbkeys.verifyObj(k, obj) // => true | |
60 | - | |
61 | -var secret = new Buffer('deadbeef', 'hex') | |
62 | -var obj = ssbkeys.signObjHmac(secret, { foo: 'bar' }) | |
63 | -console.log(obj) /* => { | |
64 | - foo: 'bar', | |
65 | - hmac: ... | |
66 | -} */ | |
67 | -ssbkeys.verifyObjHmac(secret, obj) // => true | |
68 | - | |
69 | -var authRequest = ssbkeys.createAuth(k, 'client') | |
70 | -console.log(authRequest) /* => { | |
71 | - role: 'client', | |
72 | - ts: Number, | |
73 | - public: String, | |
74 | - signature: ... | |
75 | -} */ | |
76 | -``` | |
77 | - | |
78 | -[View on Github](https://github.com/ssbc/ssb-keys) |
tmpl/apis/common/ssb-msg-schemas.html.js | ||
---|---|---|
@@ -1,8 +1,0 @@ | ||
1 | -var md = require('../../../markdown') | |
2 | -var page = require('../../page.part') | |
3 | -module.exports = () => page({ | |
4 | - section: 'apis', | |
5 | - tab: 'apis-common', | |
6 | - path: '/apis/common/ssb-msg-schemas.html', | |
7 | - content: md.doc(__dirname+'/ssb-msg-schemas.md') | |
8 | -}) |
tmpl/apis/common/ssb-msg-schemas.md | ||
---|---|---|
@@ -1,34 +1,0 @@ | ||
1 | -# ssb-msg-schemas | |
2 | - | |
3 | -Functions to create common SSB messages. | |
4 | - | |
5 | -```js | |
6 | -var schemas = require('ssb-msg-schemas') | |
7 | - | |
8 | -schemas.post( | |
9 | - text, | |
10 | - root /*optional*/, | |
11 | - branch /*optional*/, | |
12 | - mentions /*optional*/, | |
13 | - recps /*optional*/, | |
14 | - channel /*optional*/ | |
15 | -) | |
16 | -schemas.name(id, name) | |
17 | -schemas.image(id, imgLink) | |
18 | -schemas.follow(userId) | |
19 | -schemas.unfollow(userId) | |
20 | -schemas.block(userId) | |
21 | -schemas.unblock(userId) | |
22 | -schemas.vote(id, vote, reason /*optional*/) | |
23 | -schemas.pub(id, host, port) | |
24 | -``` | |
25 | - | |
26 | -Related docs: | |
27 | - - [Message schemas](/docs/advanced/message-schemas.html) | |
28 | - - [Type: post](/docs/message-types/post.html) | |
29 | - - [Type: about](/docs/message-types/about.html) | |
30 | - - [Type: contact](/docs/message-types/contact.html) | |
31 | - - [Type: vote](/docs/message-types/vote.html) | |
32 | - - [Type: pub](/docs/message-types/pub.html) | |
33 | - | |
34 | -[View on Github](https://github.com/ssbc/ssb-msg-schemas) |
tmpl/apis/common/ssb-msgs.html.js | ||
---|---|---|
@@ -1,8 +1,0 @@ | ||
1 | -var md = require('../../../markdown') | |
2 | -var page = require('../../page.part') | |
3 | -module.exports = () => page({ | |
4 | - section: 'apis', | |
5 | - tab: 'apis-common', | |
6 | - path: '/apis/common/ssb-msgs.html', | |
7 | - content: md.doc(__dirname+'/ssb-msgs.md') | |
8 | -}) |
tmpl/apis/common/ssb-msgs.md | ||
---|---|---|
@@ -1,132 +1,0 @@ | ||
1 | -# ssb-msgs | |
2 | - | |
3 | -Message-processing tools for secure-scuttlebutt | |
4 | - | |
5 | -```js | |
6 | -var mlib = require('ssb-msgs') | |
7 | -``` | |
8 | - | |
9 | -### indexLinks | |
10 | - | |
11 | -```js | |
12 | -mlib.indexLinks( | |
13 | - msg: Object, | |
14 | - { | |
15 | - rel: optional String | |
16 | - msg: optional Bool|String | |
17 | - feed: optional Bool|String | |
18 | - ext: optional Bool|String | |
19 | - }, | |
20 | - each: Function(link: Object, rel: String) | |
21 | -) | |
22 | -``` | |
23 | - | |
24 | -Traverses a message and runs the `each` function on all found links. All `opts` fields are optional. `Opts` may also be a string, in which case it is the rel attribute. | |
25 | - | |
26 | -```js | |
27 | -// assume %msgid and @feedid a well-formed | |
28 | -var msg = { | |
29 | - foo: { link: '%msgid' }, | |
30 | - bar: [{ link: '@feedid' }] | |
31 | -} | |
32 | -function print (obj, rel) { | |
33 | - console.log(rel, obj.link) | |
34 | -} | |
35 | -mlib.indexLinks(msg, print) | |
36 | -// => foo %msgid | |
37 | -// => bar @feedid | |
38 | -mlib.indexLinks(msg, 'foo', print) | |
39 | -// => foo %msgid | |
40 | -mlib.indexLinks(msg, { rel: 'foo' }, print) | |
41 | -// => foo %msgid | |
42 | -mlib.indexLinks(msg, { feed: true }, print) | |
43 | -// => bar @feedid | |
44 | -mlib.indexLinks(msg, { feed: '@feedid' }, print) | |
45 | -// => bar @feedid | |
46 | -``` | |
47 | - | |
48 | -### links | |
49 | - | |
50 | -```js | |
51 | -links(obj: Any, [requiredAttr: String]) | |
52 | -``` | |
53 | - | |
54 | -Helper to get links from a message in a regular array form. | |
55 | - | |
56 | -```js | |
57 | -var msg = { | |
58 | - foo: { link: '%msgid' }, | |
59 | - bar: [{ link: '@feedid' }] | |
60 | -} | |
61 | -mlib.links(msg.foo) // => [{ link: '%msgid' }] | |
62 | -mlib.links(msg.bar) // => [{ link: '@feedid' }] | |
63 | -mlib.links(msg.bar, 'feed') // => [{ link: '@feedid' }] | |
64 | -mlib.links(msg.bar, 'msg') // => [] | |
65 | -mlib.links(msg.baz) // => [] | |
66 | -``` | |
67 | - | |
68 | -### link | |
69 | - | |
70 | -```js | |
71 | -link(obj: Any, [requiredAttr: String]) | |
72 | -``` | |
73 | - | |
74 | -Helper to get a link from a message in a regular object form. If an array is found, will use the first element. | |
75 | - | |
76 | -```js | |
77 | -var msg = { | |
78 | - foo: { link: '%msgid' }, | |
79 | - bar: [{ link: '@feedid' }] | |
80 | -} | |
81 | -mlib.link(msg.foo) // => { link: '%msgid' } | |
82 | -mlib.link(msg.bar) // => { link: '@feedid' } | |
83 | -mlib.link(msg.bar, 'feed') // => { link: '@feedid' } | |
84 | -mlib.link(msg.bar, 'msg') // => null | |
85 | -mlib.link(msg.baz) // => null | |
86 | -``` | |
87 | - | |
88 | -### isLink | |
89 | - | |
90 | -```js | |
91 | -isLink(obj: Any, [requiredAttr: String]) | |
92 | -``` | |
93 | - | |
94 | -Predicate to test whether an object is a well-formed link. Returns false if given an array. | |
95 | - | |
96 | -```js | |
97 | -var msg = { | |
98 | - foo: { link: '%msgid' }, | |
99 | - bar: [{ link: '@feedid' }] | |
100 | -} | |
101 | -mlib.isLink(msg.foo) // => true | |
102 | -mlib.isLink(msg.bar) // => true | |
103 | -mlib.isLink(msg.bar, 'feed') // => true | |
104 | -mlib.isLink(msg.bar, 'msg') // => false | |
105 | -mlib.isLink(msg.baz) // => false | |
106 | -``` | |
107 | - | |
108 | -### linksTo | |
109 | - | |
110 | -```js | |
111 | -linksTo(a: Message, b: Message) | |
112 | -``` | |
113 | - | |
114 | -Get link objects pointing from `a` to `b`. | |
115 | - | |
116 | -```js | |
117 | -mlib.linksTo(msgA, msgB) // => [{ link: '%msgB-id' }] | |
118 | -``` | |
119 | - | |
120 | -### relationsTo | |
121 | - | |
122 | -```js | |
123 | -relationsTo(a: Message, b: Message) | |
124 | -``` | |
125 | - | |
126 | -Get relations of links pointing from `a` to `b`. | |
127 | - | |
128 | -```js | |
129 | -mlib.relationsTo(msgA, msgB) // => ['fooRelation'] | |
130 | -``` | |
131 | - | |
132 | -[View on Github](https://github.com/ssbc/ssb-msgs) |
tmpl/apis/common/ssb-ref.html.js | ||
---|---|---|
@@ -1,8 +1,0 @@ | ||
1 | -var md = require('../../../markdown') | |
2 | -var page = require('../../page.part') | |
3 | -module.exports = () => page({ | |
4 | - section: 'apis', | |
5 | - tab: 'apis-common', | |
6 | - path: '/apis/common/ssb-ref.html', | |
7 | - content: md.doc(__dirname+'/ssb-ref.md') | |
8 | -}) |
tmpl/apis/common/ssb-ref.md | ||
---|---|---|
@@ -1,32 +1,0 @@ | ||
1 | -# ssb-ref | |
2 | - | |
3 | -Check if a string is a valid ssb-reference. | |
4 | - | |
5 | -``` js | |
6 | -var ref = require('ssb-ref') | |
7 | - | |
8 | -// Check if a string is a valid ref | |
9 | -ref.isLink(str) | |
10 | - | |
11 | -// Check if a string is a feed id | |
12 | -ref.isFeedId(str) | |
13 | - | |
14 | -// Check if a string is a message id | |
15 | -ref.isMsgId(str) | |
16 | - | |
17 | -// Check if a string is a blob id | |
18 | -ref.isBlobId(str) | |
19 | - | |
20 | -// Get the type of the reference | |
21 | -ref.type(str) == 'feed' | |
22 | -ref.type(str) == 'msg' | |
23 | -ref.type(str) == 'blob' | |
24 | -ref.type('not-a-link') == false | |
25 | - | |
26 | -// Extract a ref out of a url | |
27 | -// (Url-encoding is supported) | |
28 | -ref.extract(url) | |
29 | - == '%pGzeEydYdHjKW1iIchR0Yumydsr3QSp8+FuYcwVwi8Q=.sha256' | |
30 | -``` | |
31 | - | |
32 | -[View on Github](https://github.com/ssbc/ssb-ref) |
tmpl/apis/modules/graphmitter.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/graphmitter.html', | |
7 | + content: md.doc(__dirname+'/graphmitter.md') | |
8 | +}) |
tmpl/apis/modules/graphmitter.md | ||
---|---|---|
@@ -1,0 +1,54 @@ | ||
1 | +# graphmitter | |
2 | + | |
3 | +```js | |
4 | +var Graphmitter = require('graphmitter') | |
5 | +var g = Graphmitter() | |
6 | + | |
7 | +// create edges | |
8 | +g.edge(1, 2).edge(2, 3).edge(3, 4) | |
9 | + | |
10 | +// delete an edge | |
11 | +g.del(3, 4) | |
12 | + | |
13 | +// iterate each node | |
14 | +g.each(console.log) | |
15 | +// => 1 { edges: { '2': true } } | |
16 | +// => 2 { edges: { '3': true } } | |
17 | +// => 3 { edges: { '2': true } } | |
18 | +// => 4 { edges: {} } | |
19 | + | |
20 | +// get full structure | |
21 | +g.toJSON() /* => | |
22 | +{ '1': { '2': true }, | |
23 | + '2': { '3': true }, | |
24 | + '3': {}, | |
25 | + '4': {} } | |
26 | +*/ | |
27 | + | |
28 | +// see connected nodes from a start node, including # of hops | |
29 | +g.traverse({ start: 1 }) // => { '1': 0, '2': 1, '3': 2 } | |
30 | +g.traverse({ start: 2 }) // => { '2': 0, '3': 1 } | |
31 | +g.traverse({ start: 1, hops: 1 }) // => { '1': 0, '2': 1 } | |
32 | +g.traverse({ start: 1, max: 2 }) // => { '1': 0, '2': 1 } | |
33 | + | |
34 | +// rank the connectedness of nodes using a pagerank derivative | |
35 | +g.rank() /* => | |
36 | +{ '1': 0.037500000000000006, | |
37 | + '2': 0.25, | |
38 | + '3': 0.25, | |
39 | + '4': 0.037500000000000006 } | |
40 | +*/ | |
41 | +g.edge(3, 2) | |
42 | +g.rank() /* => | |
43 | +{ '1': 0.037500000000000006, | |
44 | + '2': 0.4625, | |
45 | + '3': 0.25, | |
46 | + '4': 0.037500000000000006 } | |
47 | +*/ | |
48 | + | |
49 | +// helper to generate a random graph | |
50 | +Graphmitter.random(100, 100) // 100 nodes, 100 edges | |
51 | +``` | |
52 | + | |
53 | + | |
54 | +[View on Github](https://github.com/ssbc/graphmitter) |
tmpl/apis/modules/mdmanifest.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/mdmanifest.html', | |
7 | + content: md.doc(__dirname+'/mdmanifest.md') | |
8 | +}) |
tmpl/apis/modules/mdmanifest.md | ||
---|---|---|
@@ -1,0 +1,181 @@ | ||
1 | +# mdmanifest | |
2 | + | |
3 | +Uses a regular markdown form to produce muxrpc manifests and cli usage descriptions. | |
4 | + | |
5 | +The form: | |
6 | + | |
7 | +```markdown | |
8 | +# api-name | |
9 | + | |
10 | +Api short description. | |
11 | + | |
12 | +Api long, multiline description (optional). | |
13 | +Api long, multiline description (optional). | |
14 | +Api long, multiline description (optional). | |
15 | + | |
16 | +## method-name: type | |
17 | + | |
18 | +Method short description. | |
19 | + | |
20 | +```bash | |
21 | +bash usage (optional) | |
22 | +``` -- | |
23 | + | |
24 | +```js | |
25 | +js usage (optional) | |
26 | +``` -- | |
27 | + | |
28 | +Method long, multiline description (optional). | |
29 | +Method long, multiline description (optional). | |
30 | +Method long, multiline description (optional). | |
31 | +``` | |
32 | + | |
33 | +Example: | |
34 | + | |
35 | +```markdown | |
36 | +# example-api | |
37 | + | |
38 | +Example API, v1.0.0. | |
39 | + | |
40 | +This is an example API, written by Paul Frazee. | |
41 | +It's not a real API, but it would work with muxrpc. | |
42 | + | |
43 | +## ping: async | |
44 | + | |
45 | +Pings a target machine. | |
46 | + | |
47 | +```bash | |
48 | +ping {target string} [-n number] | |
49 | +``` -- | |
50 | + | |
51 | +```js | |
52 | +ping(target, { n: }) | |
53 | +``` -- | |
54 | + | |
55 | + - target: string, an IPv4/IPv6 address | |
56 | + - opts: | |
57 | + - n: optional number, how many times to ping | |
58 | + | |
59 | +Sends ICMP ping messages to the given target. | |
60 | +Will wait 1 second between pings. | |
61 | + | |
62 | +## listen: source | |
63 | + | |
64 | +Listens for pings. | |
65 | + | |
66 | +```bash | |
67 | +listen | |
68 | +``` -- | |
69 | + | |
70 | +```js | |
71 | +listen() | |
72 | +``` -- | |
73 | + | |
74 | +Will emit a string describing incoming pings, as they occur. | |
75 | +``` | |
76 | + | |
77 | +The api: | |
78 | + | |
79 | +```js | |
80 | +var mdm = require('mdmanifest') | |
81 | + | |
82 | +mdm.muxrpcManifest(exampleMd) | |
83 | +/* => { | |
84 | + ping: 'async', | |
85 | + listen: 'source' | |
86 | +}*/ | |
87 | + | |
88 | +mdm.usage(exampleMd) | |
89 | +/* => | |
90 | +Example API, v1.0.0. | |
91 | + | |
92 | +This is an example API, written by Paul Frazee. | |
93 | +It's not a real API, but it would work with muxrpc. | |
94 | + | |
95 | +Commands: | |
96 | + | |
97 | + - ping Pings a target machine. | |
98 | + - listen Listens for pings. | |
99 | +*/ | |
100 | + | |
101 | +mdm.usage(exampleMd, { prefix: 'foo' }) | |
102 | +/* => | |
103 | +Example API, v1.0.0. | |
104 | + | |
105 | +This is an example API, written by Paul Frazee. | |
106 | +It's not a real API, but it would work with muxrpc. | |
107 | + | |
108 | +Commands: | |
109 | + | |
110 | + - foo.ping Pings a target machine. | |
111 | + - foo.listen Listens for pings. | |
112 | +*/ | |
113 | + | |
114 | +mdm.usage(exampleMd, { nameWidth: 20 }) | |
115 | +/* => | |
116 | +Example API, v1.0.0. | |
117 | + | |
118 | +This is an example API, written by Paul Frazee. | |
119 | +It's not a real API, but it would work with muxrpc. | |
120 | + | |
121 | +Commands: | |
122 | + | |
123 | + - ping Pings a target machine. | |
124 | + - listen Listens for pings. | |
125 | +*/ | |
126 | + | |
127 | +mdm.usage(exampleMd, 'ping') | |
128 | +/* => | |
129 | +Pings a target machine. | |
130 | + | |
131 | +ping {target string} [-n number] | |
132 | + | |
133 | +- target: string, an IPv4/IPv6 address | |
134 | +- opts: | |
135 | + - n: optional number, how many times to ping | |
136 | + | |
137 | +Sends ICMP ping messages to the given target. | |
138 | +Will wait 1 second between pings. | |
139 | +*/ | |
140 | + | |
141 | +mdm.html(exampleMd) // standard HTML output | |
142 | +``` | |
143 | + | |
144 | +Command-line usage: | |
145 | + | |
146 | +```bash | |
147 | +$ ./mdm.js manifest ./test/valid-example.md | |
148 | +{ | |
149 | + "ping": "async", | |
150 | + "listen": "source" | |
151 | +} | |
152 | + | |
153 | +$ ./mdm.js html ./test/valid-example.md | |
154 | +<h1>example-api</h1> | |
155 | +<p>Example API, v1.0.0.</p> | |
156 | +... | |
157 | + | |
158 | +$ ./mdm.js usage ./test/valid-example.md | |
159 | +Example API, v1.0.0. | |
160 | + | |
161 | +This is an example API, written by Paul Frazee. | |
162 | +It's not a real API, but it would work with muxrpc. | |
163 | + | |
164 | +Commands: | |
165 | + ping Pings a target machine. | |
166 | + listen Listens for pings. | |
167 | + | |
168 | +$ ./mdm.js usage ./test/valid-example.md ping | |
169 | +Pings a target machine. | |
170 | + | |
171 | +ping {target string} [-n number] | |
172 | + | |
173 | +- target: string, an IPv4/IPv6 address | |
174 | +- opts: | |
175 | + - n: optional number, how many times to ping | |
176 | + | |
177 | +Sends ICMP ping messages to the given target. | |
178 | +Will wait 1 second between pings. | |
179 | +``` | |
180 | + | |
181 | +[View on Github](https://github.com/ssbc/mdmanifest) |
tmpl/apis/modules/muxrpc.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/muxrpc.html', | |
7 | + content: md.doc(__dirname+'/muxrpc.md') | |
8 | +}) |
tmpl/apis/modules/muxrpc.md | ||
---|---|---|
@@ -1,0 +1,149 @@ | ||
1 | +# muxrpc | |
2 | + | |
3 | +Combined rpc and multiplexing, with pull-streams. | |
4 | + | |
5 | + | |
6 | +## example | |
7 | + | |
8 | +``` js | |
9 | + | |
10 | +var MRPC = require('muxrpc') | |
11 | +var pull = require('pull-stream') | |
12 | + | |
13 | +//we need a manifest of methods we wish to expose. | |
14 | +var api = { | |
15 | + //async is a normal async function | |
16 | + hello: 'async', | |
17 | + | |
18 | + //source is a pull-stream (readable) | |
19 | + stuff: 'source' | |
20 | + | |
21 | + //TODO: sink and duplex pull-streams | |
22 | +} | |
23 | + | |
24 | +//pass the api into the constructor, | |
25 | +//and then pass the object you are wrapping | |
26 | +//(if there is a local api) | |
27 | +var client = MRPC(api, null) () //remoteApi, localApi | |
28 | +var server = MRPC(null, api) ({ | |
29 | + hello: function (name, cb) { | |
30 | + cb(null, 'hello, ' + name + '!') | |
31 | + }, | |
32 | + stuff: function () { | |
33 | + return pull.values([1, 2, 3, 4, 5]) | |
34 | + } | |
35 | +}) | |
36 | + | |
37 | +var a = client.createStream() | |
38 | +var b = server.createStream() | |
39 | + | |
40 | +pull(a, b, a) //pipe together | |
41 | + | |
42 | +client.hello('world', function (err, value) { | |
43 | + if(err) throw err | |
44 | + console.log(value) | |
45 | + // hello, world! | |
46 | +}) | |
47 | + | |
48 | +pull(client.stuff(), pull.drain(console.log)) | |
49 | +// 1 | |
50 | +// 2 | |
51 | +// 3 | |
52 | +// 4 | |
53 | +// 5 | |
54 | +``` | |
55 | + | |
56 | +## Manifest | |
57 | + | |
58 | +like multilevel, a [manifest is required](https://github.com/juliangruber/multilevel#plugins) | |
59 | +except it works a little differently, and since muxrpc works with any api, | |
60 | +not assuming leveldb then you must write the manifest yourself. | |
61 | + | |
62 | +The manifest is simply an object mapping to strings, or nested objects. | |
63 | + | |
64 | +``` js | |
65 | +{ | |
66 | + //a function with a callback. | |
67 | + foo: 'async', | |
68 | + | |
69 | + //a function that returns a value | |
70 | + //(note this is converted to | |
71 | + // an async function for the client) | |
72 | + bar: 'sync', | |
73 | + | |
74 | + //a source pull-stream (aka, readable) | |
75 | + allTheFoos: 'source', | |
76 | + | |
77 | + //a sink pull-stream (aka, writable) | |
78 | + writeFoos: 'sink', | |
79 | + | |
80 | + //a duplex pull-stream | |
81 | + fooPhone: 'duplex', | |
82 | + | |
83 | + //create nested objects like this: | |
84 | + bar: { | |
85 | + ... | |
86 | + } | |
87 | +} | |
88 | + | |
89 | +``` | |
90 | + | |
91 | +## Permissions | |
92 | + | |
93 | +If you are exposing an api over a network connection, | |
94 | +then you probably want some sort of authorization system. | |
95 | +`muxrpc@4` and earlier had a `rpc.permissions()` method on | |
96 | +the rpc object, but this has been removed. Now you must | |
97 | +provide a permissions object, which has methods `{pre, post}`. | |
98 | +`pre` is called with the path and arguments before the api | |
99 | +method is actually called, and if it returns false, then the | |
100 | +user gets an error and the method is not called. | |
101 | + | |
102 | +This is much more flexible than attaching a standard permissions | |
103 | +method--now all methods on the rpc object act the same (call remote | |
104 | +methods) and it's possible to have a method named "permissions" | |
105 | + | |
106 | +A helper module for providing permissions is provided, | |
107 | +this enables you to update permissions on the fly | |
108 | +``` js | |
109 | + | |
110 | +var Permissions = require('muxrpc/permissions') | |
111 | + | |
112 | +var api = { | |
113 | + foo: 'async', | |
114 | + bar: 'async', | |
115 | + auth: 'async' | |
116 | +} | |
117 | + | |
118 | +//set initial settings | |
119 | +var perms = Perms({allow: ['auth']}) | |
120 | + | |
121 | +var rpc = muxrpc(null, api, serializer)({ | |
122 | + foo: function (val, cb) { | |
123 | + cb(null, {okay: 'foo'}) | |
124 | + }, | |
125 | + bar: function (val, cb) { | |
126 | + cb(null, {okay: 'bar'}) | |
127 | + }, | |
128 | + auth: function (pass) { | |
129 | + //implement an auth function that sets the permissions, | |
130 | + //using allow or deny lists. | |
131 | + | |
132 | + if(pass === 'whatever') | |
133 | + perms({deny: ['bar']}) //allow everything except "bar" | |
134 | + else if(pass === 's3cr3tz') | |
135 | + perms({}) //allow everything!!! | |
136 | + else return cb(new Error('ACCESS DENIED')) | |
137 | + | |
138 | + //else we ARE authorized. | |
139 | + cb(null, 'ACCESS GRANTED') | |
140 | + } | |
141 | +}) | |
142 | + | |
143 | +//Get a stream to connect to the remote. | |
144 | +//As in the above example! | |
145 | +var ss = rpc.createStream() | |
146 | + | |
147 | +``` | |
148 | + | |
149 | +[View on Github](https://github.com/ssbc/muxrpc) |
tmpl/apis/modules/muxrpcli.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/muxrpcli.html', | |
7 | + content: md.doc(__dirname+'/muxrpcli.md') | |
8 | +}) |
tmpl/apis/modules/muxrpcli.md | ||
---|---|---|
@@ -1,0 +1,144 @@ | ||
1 | +# muxrpcli | |
2 | + | |
3 | +Command-line interface to [muxrpc](https://github.com/ssbc/muxrpc) servers. | |
4 | +Works by converting the command-line parameters into args for the RPC calls. | |
5 | +Also adds some standard behaviors for usage calls. | |
6 | + | |
7 | +**Standard Switches**: | |
8 | + | |
9 | + - `--oneline` put json output on one line. | |
10 | + - `-h / --help` usage. | |
11 | + | |
12 | +## CLI Parameters | |
13 | + | |
14 | +Parameters are parsed with [minimist](https://www.npmjs.com/package/minimist). | |
15 | +The first positional param is mapped to the rpc command. | |
16 | +Any subsequent positional params are passed as arguments. | |
17 | +Then, the object constructed by the named parameters (if there are any) is passed as the last argument. | |
18 | + | |
19 | +Examples: | |
20 | + | |
21 | +```bash | |
22 | +$ program command arg1 arg2 | |
23 | +invokes server.command("arg1", "arg2") | |
24 | + | |
25 | +$ program command -a beep -b boop | |
26 | +invokes server.command({ a: "beep", b: "boob" }) | |
27 | + | |
28 | +$ program command arg1 arg2 -a beep -b boop | |
29 | +invokes server.command("arg1", "arg2", { | |
30 | + a: "beep", | |
31 | + b: "boob" | |
32 | +}) | |
33 | + | |
34 | +$ program command -a beep -b boop arg1 arg2 | |
35 | +invokes server.command("arg1", "arg2", { | |
36 | + a: "beep", | |
37 | + b: "boob" | |
38 | +}) | |
39 | +``` | |
40 | + | |
41 | +If a stream is supplied to stdin, it will be parsed as JSON and used instead of the CLI parameters. | |
42 | + | |
43 | +```bash | |
44 | +$ echo '{"a":"beep","b":"boop"}' | program command | |
45 | +invokes `server.command({ a: "beep", b: "boob" })' | |
46 | +``` | |
47 | + | |
48 | + | |
49 | +## Usage calls | |
50 | + | |
51 | +Usage-calls are the help which is output when a command fails, or when help is requested. | |
52 | +They are used in the following situations: | |
53 | + | |
54 | + - If the command does not exist in the RPC server's manifest, does a top-level usage call. | |
55 | + - If the command responses with a `TypeError`, `UsageError`, `BadParamError`, or `BadArgError`, does a usage call for that command. | |
56 | + - If the `-h` or `--help` switches are given, does a toplevel or command usage call. | |
57 | + | |
58 | +A usage-call is a call to the `usage(cmd)` function on the RPC server. | |
59 | +A 'top-level' usage call will leave `cmd` falsey. | |
60 | +The `usage` method should return a string to display. | |
61 | + | |
62 | + | |
63 | +## Example rpc server | |
64 | + | |
65 | +```js | |
66 | +var zerr = require('zerr') | |
67 | +var MissingArgError = zerr('BadArg', '"%" is required') | |
68 | +var BadTypeError = zerr('BadArg', '"%" must be a valid %') | |
69 | + | |
70 | +var manifest = { | |
71 | + usage: 'sync', | |
72 | + whoami: 'sync', | |
73 | + ping: 'async' | |
74 | +} | |
75 | +var api = {} | |
76 | +// muxrpc(null, manifest)(api) is called | |
77 | + | |
78 | +api.usage = function (cmd) { | |
79 | + switch (cmd) { | |
80 | + case 'whoami': | |
81 | + return 'whoami. get your profile info.' | |
82 | + case 'ping': | |
83 | + return 'ping {target} [-n times]. '+ | |
84 | + 'send `n` pings to `target`, defaults to 1' | |
85 | + } | |
86 | + return [ | |
87 | + 'myexample usage:' | |
88 | + ' - ' + api.usage('whoami'), | |
89 | + ' - ' + api.usage('ping') | |
90 | + ].join('\n') | |
91 | +} | |
92 | + | |
93 | +api.whoami = function() { return 'bob, obviously' } | |
94 | + | |
95 | +api.ping = function(target, opts, cb) { | |
96 | + if (!target) return cb(MissingArgError('target')) | |
97 | + if (!isAddress(target)) | |
98 | + return cb(BadTypeError('target', 'address')) | |
99 | + | |
100 | + var n = 1 | |
101 | + if (opts && opts.n) { | |
102 | + n = +opts.n | |
103 | + if (isNaN(n)) return cb(BadTypeError('n', 'number')) | |
104 | + } | |
105 | + | |
106 | + // ... | |
107 | +} | |
108 | +``` | |
109 | + | |
110 | +Here's how a session would behave with this server: | |
111 | + | |
112 | +```bash | |
113 | +$ myexample | |
114 | +myexample usage: | |
115 | + - whoami. get your profile info. | |
116 | + - ping {target} [-n times]. send `n` pings to `target`. | |
117 | +defaults to 1 | |
118 | + | |
119 | +$ myexample whoami -h | |
120 | +whoami. get your profile info. | |
121 | + | |
122 | +$ myexample ping -h | |
123 | +ping {target} [-n times]. send `n` pings to `target`. | |
124 | +defaults to 1 | |
125 | + | |
126 | +$ myexample whoami | |
127 | +bob, obviously | |
128 | + | |
129 | +$ myexample ping 127.0.0.1 | |
130 | +... | |
131 | + | |
132 | +$ myexample ping 1123123123 | |
133 | +[BadArgError: "target" must be a valid address] | |
134 | +ping {target} [-n times]. send `n` pings to `target`. | |
135 | +defaults to 1 | |
136 | + | |
137 | + | |
138 | +$ myexample ping 127.0.0.1 -n foobar | |
139 | +[BadArgError: "n" must be a valid number] | |
140 | +ping {target} [-n times]. send `n` pings to `target`. | |
141 | +defaults to 1 | |
142 | +``` | |
143 | + | |
144 | +[View on Github](https://github.com/ssbc/muxrpcli) |
tmpl/apis/modules/secret-stack.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/secret-stack.html', | |
7 | + content: md.doc(__dirname+'/secret-stack.md') | |
8 | +}) |
tmpl/apis/modules/secret-stack.md | ||
---|---|---|
@@ -1,0 +1,124 @@ | ||
1 | +# secret-stack | |
2 | + | |
3 | +Create secure peer to peer networks using secret-handshakes. | |
4 | + | |
5 | +SecretStack is built on [secret-handshake](https://github.com/dominictarr/secret-handshake) | |
6 | +and [muxrpc](https://github.com/ssbc/muxrpc). This provides a framework | |
7 | +to make building secure, decentralized systems easier. | |
8 | +(such as [scuttlebot](https://github.com/ssbc/scuttlebot) which this was refactored out of ;) | |
9 | + | |
10 | +## Example | |
11 | + | |
12 | +``` js | |
13 | +var SecretStack = require('secret-stack') | |
14 | + | |
15 | +var createApp = SecretStack({ | |
16 | + appKey: appKey //32 random bytes | |
17 | +}) | |
18 | +.use({ | |
19 | + //plugin | |
20 | + //name of the plugin, this is where it will be "mounted" | |
21 | + name: 'foo', | |
22 | + //muxrpc manifest | |
23 | + manifest: { | |
24 | + bar: 'async' | |
25 | + }, | |
26 | + //permissions will be merged into the main permissions, | |
27 | + //prefixed with the plugin name. | |
28 | + //so theirfore this becomes 'foo.bar'. | |
29 | + permissions: { | |
30 | + anonymous: [ | |
31 | + 'bar' | |
32 | + ] | |
33 | + } | |
34 | + init: function (api, opts) { | |
35 | + //set up and return some methods... | |
36 | + return { | |
37 | + bar: function (arg, cb) { | |
38 | + //do something async | |
39 | + cb(null, result) | |
40 | + }) | |
41 | + } | |
42 | + } | |
43 | +}) | |
44 | +``` | |
45 | + | |
46 | +## create = SecretStack(opts) | |
47 | + | |
48 | +initialize a new app factory. | |
49 | +opts must have a property `appKey` which should | |
50 | +be a high entropy (i.e. random) 32 byte value. | |
51 | +It is fixed for your app. Actors who do not know this value | |
52 | +will not be able to connect to instances of your app. | |
53 | + | |
54 | +### create.use(plugin) | |
55 | + | |
56 | +set up the factory by adding plugins. see the example above. | |
57 | + | |
58 | +### plugin.init (api, opts) | |
59 | + | |
60 | +each plugin init function is called in the order they where | |
61 | +added and it may return an object which is combined into the api. | |
62 | +if `plugin.name` is a string, then it's added as `api[plugin.name]=plugin.init(api, opts)` | |
63 | +else, it's merged with the api object. | |
64 | + | |
65 | +Note, each method on the api gets wrapped with [hoox](https://github.com/dominictarr/hoox) | |
66 | +so that plugins may intercept that function. | |
67 | +So far, the ways i have used this is to manage permissions, | |
68 | +for example, to extend the auth method (see below) or to filter | |
69 | +the output of a stream. | |
70 | + | |
71 | +### connect = create.createClient(opts) | |
72 | + | |
73 | +sometimes you need to create a connection using a different key pair, | |
74 | +and/or to connect without providing access for the remote to your local api. | |
75 | +`opts` must have a sodium ed25519 key pair, or a `seed` (32 byte random) | |
76 | +value, from which a private key will be generated. | |
77 | + | |
78 | +`connect` then takes the same arguments as `node.connect` | |
79 | + | |
80 | +### node = create (opts) | |
81 | + | |
82 | +create an actual instance! opts must have a `keys` property | |
83 | +which is a sodium ed25519 key pair. | |
84 | + | |
85 | +### node.getAddress() | |
86 | + | |
87 | +get a string representing the address of this node. | |
88 | +it will be `ip:port:<base64:pubkey>`. | |
89 | + | |
90 | +### node.connect(address, cb) | |
91 | + | |
92 | +create a rpc connection to another instance. | |
93 | +Address should be the form returned by `getAddress` | |
94 | + | |
95 | +### node.auth(publicKey, cb) | |
96 | + | |
97 | +Query what permissions a given public key is assigned. | |
98 | +it's not intended for this to be exposed over the network, | |
99 | +but rather to extend this method to create plugable permissions systems. | |
100 | + | |
101 | +``` js | |
102 | +node.auth.hook(function (auth, args) { | |
103 | + var pub = args[0] | |
104 | + var cb = args[1] | |
105 | + //call the first auth fn, and then hook the callback. | |
106 | + auth(pub, function (err, perms) { | |
107 | + if(err) cb(err) | |
108 | + //optionally set your own perms for this pubkey. | |
109 | + else if(accepted) | |
110 | + cb(null, permissions) | |
111 | + | |
112 | + //or if you wish to reject them | |
113 | + else if(rejected) | |
114 | + cb(new Error('reject')) | |
115 | + | |
116 | + //fallback to default | |
117 | + //(the next hook, or the anonymous config, if defined) | |
118 | + else | |
119 | + cb() | |
120 | + }) | |
121 | +}) | |
122 | +``` | |
123 | + | |
124 | +[View on Github](https://github.com/ssbc/secret-stack) |
tmpl/apis/modules/ssb-client.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/ssb-client.html', | |
7 | + content: md.doc(__dirname+'/ssb-client.md') | |
8 | +}) |
tmpl/apis/modules/ssb-client.md | ||
---|---|---|
@@ -1,0 +1,29 @@ | ||
1 | +# ssb-client | |
2 | + | |
3 | +Scuttlebot client. | |
4 | + | |
5 | +```js | |
6 | +var ssbClient = require('ssb-client') | |
7 | + | |
8 | +// simplest usage, connect to localhost sbot | |
9 | +ssbClient(function (err, sbot) { | |
10 | + // ... | |
11 | +}) | |
12 | + | |
13 | +// configuration: | |
14 | +var keys = ssbKeys.loadOrCreateSync('./app-private.key') | |
15 | +ssbClient( | |
16 | + keys, // optional, defaults to ~/.ssb/secret | |
17 | + { | |
18 | + host: 'localhost', // optional, defaults to localhost | |
19 | + port: 8008, // optional, defaults to 8008 | |
20 | + key: keys.id // optional, defaults to keys.id | |
21 | + }, | |
22 | + function (err, sbot) { | |
23 | + // ... | |
24 | + } | |
25 | +) | |
26 | + | |
27 | +``` | |
28 | + | |
29 | +[View on Github](https://github.com/ssbc/ssb-client) |
tmpl/apis/modules/ssb-config.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/ssb-config.html', | |
7 | + content: md.doc(__dirname+'/ssb-config.md') | |
8 | +}) |
tmpl/apis/modules/ssb-config.md | ||
---|---|---|
@@ -1,0 +1,36 @@ | ||
1 | +# ssb-config | |
2 | + | |
3 | +Configuration module used by [`scuttlebot`](https://github.com/ssbc/scuttlebot). | |
4 | + | |
5 | +## example | |
6 | + | |
7 | +``` js | |
8 | +var config = require('ssb-config') | |
9 | + | |
10 | +// if you want to set up a test network, that | |
11 | +// doesn't collide with main ssb network, | |
12 | +// pass the name of that network in. | |
13 | + | |
14 | +var test_config = require('ssb-config/inject')( | |
15 | + 'testnet', // name | |
16 | + { port: 9999 } // opts | |
17 | +) | |
18 | +// you can also pass a second argument, | |
19 | +// which overrides the default opts. | |
20 | +``` | |
21 | + | |
22 | +## Configuration | |
23 | + | |
24 | +* `host` *(string)* The domain or ip address for `sbot`. Defaults to your public ip address. | |
25 | +* `port` *(string|number)* The port for `sbot`. Defaults to `8008`. | |
26 | +* `timeout`: *(number)* Number of milliseconds a replication stream can idle before it's automatically disconnected. Defaults to `30000`. | |
27 | +* `pub` *(boolean)* Replicate with pub servers. Defaults to `true`. | |
28 | +* `local` *(boolean)* Replicate with local servers found on the same network via `udp`. Defaults to `true`. | |
29 | +* `friends.dunbar` *(number)* [`Dunbar's number`](https://en.wikipedia.org/wiki/Dunbar%27s_number). Number of nodes your instance will replicate. Defaults to `150`. | |
30 | +* `friends.hops` *(number)* How many friend of friend hops to replicate. Defaults to `3`. | |
31 | +* `gossip.connections` *(number)* How many other nodes to connect with at one time. Defaults to `2`. | |
32 | +* `path` *(string)* Path to the application data folder, which contains the private key, message attachment data (blobs) and the leveldb backend. Defaults to `$HOME/.ssb`. | |
33 | + | |
34 | +There are some configuration options for the sysadmins out there. All configuration is loaded via [`rc`](https://github.com/dominictarr/rc). You can pass any configuration value in as cli arg, env var, or in a file. | |
35 | + | |
36 | +[View on Github](https://github.com/ssbc/ssb-config) |
tmpl/apis/modules/ssb-feed.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/ssb-feed.html', | |
7 | + content: md.doc(__dirname+'/ssb-feed.md') | |
8 | +}) |
tmpl/apis/modules/ssb-feed.md | ||
---|---|---|
@@ -1,0 +1,34 @@ | ||
1 | +# ssb-feed | |
2 | + | |
3 | +A publishing interface for scuttlebutt feeds. | |
4 | + | |
5 | +By default, Scuttlebot uses a "master" identity/feed, which `sbot.publish()` will append new messages to. If you want to manipulate additional feeds, you can load the keypair and then use this library to do so. | |
6 | + | |
7 | +## Example | |
8 | + | |
9 | +``` js | |
10 | + | |
11 | +var ssbFeed = require('ssb-feed') | |
12 | +var ssbClient = require('ssb-client') | |
13 | +var ssbKeys = require('ssb-keys') | |
14 | + | |
15 | +var alice = ssbKeys.generate() | |
16 | +ssbClient(function (err, sbot) { | |
17 | + var feed = ssbFeed(sbot, alice) | |
18 | + | |
19 | + // Post to alice's feed | |
20 | + feed.publish({ | |
21 | + type: 'post', | |
22 | + text: 'hello world, I am alice.' | |
23 | + }, function (err) { ... }) | |
24 | + | |
25 | + // Also available: | |
26 | + console.log(feed.id) | |
27 | + console.log(feed.keys) | |
28 | +}) | |
29 | +``` | |
30 | + | |
31 | +This example uses `ssb-client`, but, if you're embedding `scuttlebot` or the `secure-scuttlebutt` library into your process, you can use them locally. | |
32 | + | |
33 | +[View on Github](https://github.com/ssbc/ssb-feed) | |
34 | + |
tmpl/apis/modules/ssb-keys.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/ssb-keys.html', | |
7 | + content: md.doc(__dirname+'/ssb-keys.md') | |
8 | +}) |
tmpl/apis/modules/ssb-keys.md | ||
---|---|---|
@@ -1,0 +1,78 @@ | ||
1 | +# ssb-keys | |
2 | + | |
3 | +A common module for secure-scuttlebutt projects, provides an API to create or load elliptic-curve keypairs and to execute related crypto operations. | |
4 | + | |
5 | +```js | |
6 | +var ssbkeys = require('ssb-keys') | |
7 | + | |
8 | +ssbkeys.create(path, function(err, k) { | |
9 | + console.log(k) /* => { | |
10 | + id: String, | |
11 | + public: String, | |
12 | + private: String | |
13 | + }*/ | |
14 | +}) | |
15 | + | |
16 | +ssbkeys.load(path, function(err, k) { | |
17 | + console.log(k) /* => { | |
18 | + id: String, | |
19 | + public: String, | |
20 | + private: String | |
21 | + }*/ | |
22 | +}) | |
23 | + | |
24 | +var k = ssbkeys.createSync(path) | |
25 | +console.log(k) /* => { | |
26 | + id: String, | |
27 | + public: String, | |
28 | + private: String | |
29 | +}*/ | |
30 | + | |
31 | +var k = ssbkeys.loadSync(path) | |
32 | +console.log(k) /* => { | |
33 | + id: String, | |
34 | + public: String, | |
35 | + private: String | |
36 | +}*/ | |
37 | + | |
38 | +var k = ssbkeys.generate() | |
39 | +console.log(k) /* => { | |
40 | + id: String, | |
41 | + public: String, | |
42 | + private: String | |
43 | +}*/ | |
44 | + | |
45 | +var hash = ssbkeys.hash(new Buffer('deadbeef', 'hex')) | |
46 | +ssbkeys.isHash(hash) // => true | |
47 | + | |
48 | +var sig = ssbkeys.sign(k, hash) | |
49 | +ssbkeys.verify(k.public, sig, hash) // => true | |
50 | + | |
51 | +var secret = new Buffer('deadbeef', 'hex') | |
52 | +ssbkeys.hmac(secret, k.private) // => String | |
53 | + | |
54 | +var obj = ssbkeys.signObj(k, { foo: 'bar' }) | |
55 | +console.log(obj) /* => { | |
56 | + foo: 'bar', | |
57 | + signature: ... | |
58 | +} */ | |
59 | +ssbkeys.verifyObj(k, obj) // => true | |
60 | + | |
61 | +var secret = new Buffer('deadbeef', 'hex') | |
62 | +var obj = ssbkeys.signObjHmac(secret, { foo: 'bar' }) | |
63 | +console.log(obj) /* => { | |
64 | + foo: 'bar', | |
65 | + hmac: ... | |
66 | +} */ | |
67 | +ssbkeys.verifyObjHmac(secret, obj) // => true | |
68 | + | |
69 | +var authRequest = ssbkeys.createAuth(k, 'client') | |
70 | +console.log(authRequest) /* => { | |
71 | + role: 'client', | |
72 | + ts: Number, | |
73 | + public: String, | |
74 | + signature: ... | |
75 | +} */ | |
76 | +``` | |
77 | + | |
78 | +[View on Github](https://github.com/ssbc/ssb-keys) |
tmpl/apis/modules/ssb-msg-schemas.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/ssb-msg-schemas.html', | |
7 | + content: md.doc(__dirname+'/ssb-msg-schemas.md') | |
8 | +}) |
tmpl/apis/modules/ssb-msg-schemas.md | ||
---|---|---|
@@ -1,0 +1,34 @@ | ||
1 | +# ssb-msg-schemas | |
2 | + | |
3 | +Functions to create common SSB messages. | |
4 | + | |
5 | +```js | |
6 | +var schemas = require('ssb-msg-schemas') | |
7 | + | |
8 | +schemas.post( | |
9 | + text, | |
10 | + root /*optional*/, | |
11 | + branch /*optional*/, | |
12 | + mentions /*optional*/, | |
13 | + recps /*optional*/, | |
14 | + channel /*optional*/ | |
15 | +) | |
16 | +schemas.name(id, name) | |
17 | +schemas.image(id, imgLink) | |
18 | +schemas.follow(userId) | |
19 | +schemas.unfollow(userId) | |
20 | +schemas.block(userId) | |
21 | +schemas.unblock(userId) | |
22 | +schemas.vote(id, vote, reason /*optional*/) | |
23 | +schemas.pub(id, host, port) | |
24 | +``` | |
25 | + | |
26 | +Related docs: | |
27 | + - [Message schemas](/docs/advanced/message-schemas.html) | |
28 | + - [Type: post](/docs/message-types/post.html) | |
29 | + - [Type: about](/docs/message-types/about.html) | |
30 | + - [Type: contact](/docs/message-types/contact.html) | |
31 | + - [Type: vote](/docs/message-types/vote.html) | |
32 | + - [Type: pub](/docs/message-types/pub.html) | |
33 | + | |
34 | +[View on Github](https://github.com/ssbc/ssb-msg-schemas) |
tmpl/apis/modules/ssb-msgs.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/ssb-msgs.html', | |
7 | + content: md.doc(__dirname+'/ssb-msgs.md') | |
8 | +}) |
tmpl/apis/modules/ssb-msgs.md | ||
---|---|---|
@@ -1,0 +1,132 @@ | ||
1 | +# ssb-msgs | |
2 | + | |
3 | +Message-processing tools for secure-scuttlebutt | |
4 | + | |
5 | +```js | |
6 | +var mlib = require('ssb-msgs') | |
7 | +``` | |
8 | + | |
9 | +### indexLinks | |
10 | + | |
11 | +```js | |
12 | +mlib.indexLinks( | |
13 | + msg: Object, | |
14 | + { | |
15 | + rel: optional String | |
16 | + msg: optional Bool|String | |
17 | + feed: optional Bool|String | |
18 | + ext: optional Bool|String | |
19 | + }, | |
20 | + each: Function(link: Object, rel: String) | |
21 | +) | |
22 | +``` | |
23 | + | |
24 | +Traverses a message and runs the `each` function on all found links. All `opts` fields are optional. `Opts` may also be a string, in which case it is the rel attribute. | |
25 | + | |
26 | +```js | |
27 | +// assume %msgid and @feedid a well-formed | |
28 | +var msg = { | |
29 | + foo: { link: '%msgid' }, | |
30 | + bar: [{ link: '@feedid' }] | |
31 | +} | |
32 | +function print (obj, rel) { | |
33 | + console.log(rel, obj.link) | |
34 | +} | |
35 | +mlib.indexLinks(msg, print) | |
36 | +// => foo %msgid | |
37 | +// => bar @feedid | |
38 | +mlib.indexLinks(msg, 'foo', print) | |
39 | +// => foo %msgid | |
40 | +mlib.indexLinks(msg, { rel: 'foo' }, print) | |
41 | +// => foo %msgid | |
42 | +mlib.indexLinks(msg, { feed: true }, print) | |
43 | +// => bar @feedid | |
44 | +mlib.indexLinks(msg, { feed: '@feedid' }, print) | |
45 | +// => bar @feedid | |
46 | +``` | |
47 | + | |
48 | +### links | |
49 | + | |
50 | +```js | |
51 | +links(obj: Any, [requiredAttr: String]) | |
52 | +``` | |
53 | + | |
54 | +Helper to get links from a message in a regular array form. | |
55 | + | |
56 | +```js | |
57 | +var msg = { | |
58 | + foo: { link: '%msgid' }, | |
59 | + bar: [{ link: '@feedid' }] | |
60 | +} | |
61 | +mlib.links(msg.foo) // => [{ link: '%msgid' }] | |
62 | +mlib.links(msg.bar) // => [{ link: '@feedid' }] | |
63 | +mlib.links(msg.bar, 'feed') // => [{ link: '@feedid' }] | |
64 | +mlib.links(msg.bar, 'msg') // => [] | |
65 | +mlib.links(msg.baz) // => [] | |
66 | +``` | |
67 | + | |
68 | +### link | |
69 | + | |
70 | +```js | |
71 | +link(obj: Any, [requiredAttr: String]) | |
72 | +``` | |
73 | + | |
74 | +Helper to get a link from a message in a regular object form. If an array is found, will use the first element. | |
75 | + | |
76 | +```js | |
77 | +var msg = { | |
78 | + foo: { link: '%msgid' }, | |
79 | + bar: [{ link: '@feedid' }] | |
80 | +} | |
81 | +mlib.link(msg.foo) // => { link: '%msgid' } | |
82 | +mlib.link(msg.bar) // => { link: '@feedid' } | |
83 | +mlib.link(msg.bar, 'feed') // => { link: '@feedid' } | |
84 | +mlib.link(msg.bar, 'msg') // => null | |
85 | +mlib.link(msg.baz) // => null | |
86 | +``` | |
87 | + | |
88 | +### isLink | |
89 | + | |
90 | +```js | |
91 | +isLink(obj: Any, [requiredAttr: String]) | |
92 | +``` | |
93 | + | |
94 | +Predicate to test whether an object is a well-formed link. Returns false if given an array. | |
95 | + | |
96 | +```js | |
97 | +var msg = { | |
98 | + foo: { link: '%msgid' }, | |
99 | + bar: [{ link: '@feedid' }] | |
100 | +} | |
101 | +mlib.isLink(msg.foo) // => true | |
102 | +mlib.isLink(msg.bar) // => true | |
103 | +mlib.isLink(msg.bar, 'feed') // => true | |
104 | +mlib.isLink(msg.bar, 'msg') // => false | |
105 | +mlib.isLink(msg.baz) // => false | |
106 | +``` | |
107 | + | |
108 | +### linksTo | |
109 | + | |
110 | +```js | |
111 | +linksTo(a: Message, b: Message) | |
112 | +``` | |
113 | + | |
114 | +Get link objects pointing from `a` to `b`. | |
115 | + | |
116 | +```js | |
117 | +mlib.linksTo(msgA, msgB) // => [{ link: '%msgB-id' }] | |
118 | +``` | |
119 | + | |
120 | +### relationsTo | |
121 | + | |
122 | +```js | |
123 | +relationsTo(a: Message, b: Message) | |
124 | +``` | |
125 | + | |
126 | +Get relations of links pointing from `a` to `b`. | |
127 | + | |
128 | +```js | |
129 | +mlib.relationsTo(msgA, msgB) // => ['fooRelation'] | |
130 | +``` | |
131 | + | |
132 | +[View on Github](https://github.com/ssbc/ssb-msgs) |
tmpl/apis/modules/ssb-ref.html.js | ||
---|---|---|
@@ -1,0 +1,8 @@ | ||
1 | +var md = require('../../../markdown') | |
2 | +var page = require('../../page.part') | |
3 | +module.exports = () => page({ | |
4 | + section: 'apis', | |
5 | + tab: 'apis-modules', | |
6 | + path: '/apis/modules/ssb-ref.html', | |
7 | + content: md.doc(__dirname+'/ssb-ref.md') | |
8 | +}) |
tmpl/apis/modules/ssb-ref.md | ||
---|---|---|
@@ -1,0 +1,32 @@ | ||
1 | +# ssb-ref | |
2 | + | |
3 | +Check if a string is a valid ssb-reference. | |
4 | + | |
5 | +``` js | |
6 | +var ref = require('ssb-ref') | |
7 | + | |
8 | +// Check if a string is a valid ref | |
9 | +ref.isLink(str) | |
10 | + | |
11 | +// Check if a string is a feed id | |
12 | +ref.isFeedId(str) | |
13 | + | |
14 | +// Check if a string is a message id | |
15 | +ref.isMsgId(str) | |
16 | + | |
17 | +// Check if a string is a blob id | |
18 | +ref.isBlobId(str) | |
19 | + | |
20 | +// Get the type of the reference | |
21 | +ref.type(str) == 'feed' | |
22 | +ref.type(str) == 'msg' | |
23 | +ref.type(str) == 'blob' | |
24 | +ref.type('not-a-link') == false | |
25 | + | |
26 | +// Extract a ref out of a url | |
27 | +// (Url-encoding is supported) | |
28 | +ref.extract(url) | |
29 | + == '%pGzeEydYdHjKW1iIchR0Yumydsr3QSp8+FuYcwVwi8Q=.sha256' | |
30 | +``` | |
31 | + | |
32 | +[View on Github](https://github.com/ssbc/ssb-ref) |
tmpl/leftnav.part.js | ||
---|---|---|
@@ -55,17 +55,28 @@ | ||
55 | 55 | ${item(c, '/apis/scuttlebot/private.html', 'Private')} |
56 | 56 | ${item(c, '/apis/scuttlebot/replicate.html', 'Replicate')} |
57 | 57 | </ul>` |
58 | 58 | |
59 | -module.exports['apis-common'] = (c) => `<ul class="nav"> | |
60 | - ${item(c, '/apis/common/ssb-client.html', 'SSB-Client')} | |
61 | - ${item(c, '/apis/common/ssb-feed.html', 'SSB-Feed')} | |
62 | - ${item(c, '/apis/common/ssb-keys.html', 'SSB-Keys')} | |
63 | - ${item(c, '/apis/common/ssb-ref.html', 'SSB-Ref')} | |
64 | - ${item(c, '/apis/common/ssb-msgs.html', 'SSB-Msgs')} | |
65 | - ${item(c, '/apis/common/ssb-msg-schemas.html', 'SSB-Msg-Schemas')} | |
59 | +module.exports['apis-modules'] = (c) => `<ul class="nav"> | |
60 | + ${item(c, '/apis/modules/ssb-client.html', 'SSB-Client')} | |
61 | + ${item(c, '/apis/modules/ssb-feed.html', 'SSB-Feed')} | |
62 | + ${item(c, '/apis/modules/ssb-keys.html', 'SSB-Keys')} | |
63 | + ${item(c, '/apis/modules/ssb-ref.html', 'SSB-Ref')} | |
64 | + ${item(c, '/apis/modules/ssb-msgs.html', 'SSB-Msgs')} | |
65 | + ${item(c, '/apis/modules/ssb-msg-schemas.html', 'SSB-Msg-Schemas')} | |
66 | + ${item(c, '/apis/modules/ssb-config.html', 'SSB-Config')} | |
67 | + ${item(c, '/apis/modules/secret-stack.html', 'Secret-Stack')} | |
68 | + ${item(c, '/apis/modules/muxrpc.html', 'MuxRPC')} | |
69 | + ${item(c, '/apis/modules/muxrpcli.html', 'MuxRPCCli')} | |
70 | + ${item(c, '/apis/modules/mdmanifest.html', 'MDManifest')} | |
71 | + ${item(c, '/apis/modules/graphmitter.html', 'Graphmitter')} | |
66 | 72 | </ul>` |
67 | 73 | |
74 | +module.exports['apis-pull-stream'] = (c) => `<ul class="nav"> | |
75 | + ${item(c, '/apis/pull-stream/pull-stream.html', 'Pull-Stream')} | |
76 | + ${item(c, '/apis/pull-stream/pull-ws-server.html', 'Pull-WS-Server')} | |
77 | +` | |
78 | + | |
68 | 79 | module.exports['guides-concepts'] = (c) => `<ul class="nav"> |
69 | 80 | ${item(c, '/guides/concepts/intro.html', 'Intro')} |
70 | 81 | </ul>` |
71 | 82 |
tmpl/tabs.part.js | ||
---|---|---|
@@ -21,11 +21,11 @@ | ||
21 | 21 | </div>` |
22 | 22 | |
23 | 23 | module.exports.apis = (c) => `<div class="tabs small"> |
24 | 24 | ${item(c, 'apis-scuttlebot', '/apis/scuttlebot/ssb.html', 'Scuttlebot')} |
25 | - ${item(c, 'apis-common', '/apis/common/ssb-client.html', 'Common Modules')} | |
26 | - ${item(c, 'apis-internal', '/apis/internal/muxrpc.html', 'Internal Modules')} | |
27 | - ${item(c, 'apis-community', '/apis/community/ssbify.html', 'Community Modules')} | |
25 | + ${item(c, 'apis-modules', '/apis/modules/ssb-client.html', 'Modules')} | |
26 | + ${item(c, 'apis-pull-stream', '/apis/pull-stream/ssb-client.html', 'Pull Stream')} | |
27 | + ${item(c, 'apis-community', '/apis/community/ssbify.html', 'Community')} | |
28 | 28 | </div>` |
29 | 29 | |
30 | 30 | module.exports.apps = (c) => `<div class="tabs small"> |
31 | 31 | ${item(c, 'basics', '/basics/install-the-database.html', 'Basics')} |
Built with git-ssb-web