git ssb

1+

mixmix / scuttle-book



Commit e9238520ce96e4b6ad803bf181a65eb9d888feb4

make basic book.obs.get (no updates yet)

mix irving committed on 1/28/2018, 10:23:04 PM
Parent: c4f0656414375ade1e3c819a7b61d5808010551c

Files changed

README.mdchanged
async/comment.jschanged
async/create.jschanged
async/isBookComment.jschanged
async/isBookUpdate.jschanged
index.jschanged
obs/book.jsdeleted
obs/get.jsadded
package-lock.jsonchanged
package.jsonchanged
sync/isBook.jschanged
tests/isBook.jsdeleted
tests/obs/get.jsadded
tests/sync/isBook.jsadded
schemas/book.jsdeleted
schemas/bookComment.jsdeleted
schemas/bookUpdate.jsdeleted
schema/book.jsadded
schema/bookComment.jsadded
schema/bookUpdate.jsadded
README.mdView
@@ -10,9 +10,9 @@
1010 ## Usage
1111
1212 ```js
1313 const Book = require('scuttle-book')
14-const book = Book(client) // an ssb-client (sbot)
14 +const book = Book(server) // server is sometimes called sbot
1515
1616 const newBook = {
1717 title: 'The Dispossessed',
1818 author: 'Ursula le Guin'
@@ -28,11 +28,11 @@
2828 ```
2929
3030 ## Constructor API
3131
32-### `Book(client, opts)`
32 +### `Book(server, opts)`
3333
34-`client` an ssb-client instance (sometimes called sbot in other docs).
34 +`server` is a connection to your scuttlebutt server provided by `ssb-client` (sometimes called sbot in other docs).
3535
3636 `opts` (options) an Object with over-ride options for the scuttle-book instance:
3737
3838 ```js
@@ -51,28 +51,29 @@
5151 ## Instance API
5252
5353 ### `book.async.create(book, cb)`
5454
55-`book` - an Object which must at least have `title`, `author`
55 +`book` - an Object which must at least have `title`, `author`. If a book doesn't pass the `isBook` validator, the callback is called with the errors : `cb(errors)`
5656
5757 ### `book.async.update(id, attributes, cb)`
5858 ### `book.async.comment(id, text, cb)`
5959
6060 ### `book.sync.isBook(bookMsg)`
6161
62-Checks if a given message is a valid book message.
62 +Checks if a given message is a valid book message, where a 'message' can be either a raw message from the database or `msg.value.content`.
6363
6464 This method doesn't need an sbot connection so can be accessed directly like:
6565
6666 ```js
6767 const isBook = require('scuttle-book/isBook')
6868 ```
6969
70-### `book.async.isBook(id, cb)`
7170
72-Looks up an id to see if it's a valid book message.
71 +### `book.async.isBookKey(key, cb)`
7372
73 +Looks up a `key` to see if it belongs to a valid book message.
7474
75 +
7576 ### `book.async.isBookUpdate(aboutMsg, cb)`
7677
7778 Check if it's an `about` message, and directed at a valid book message.
7879
@@ -91,21 +92,26 @@
9192 ### `book.pull.updates()`
9293
9394 A stream of updates on books. You can filter this yourself to pull out just ratings, or description updates etc).
9495
95-### `book.obs.get(id)`
96 +### `book.obs.get(key)`
9697
9798 Returns an observeable which provides live updating data for a particular book.
9899
99100 ```js
100-var favBook = book.obs.book('%A4RPANAIiCtO9phwbL0tqk9ta4ltzzZwECZjsH25rqY=.sha256"')
101 +var favBook = book.obs.get('%A4RPANAIiCtO9phwbL0tqk9ta4ltzzZwECZjsH25rqY=.sha256"')
101102
102103 favBook( function listener (newBookState) {
103104 // this function is passed the newBookState whenever there's an update
104105 })
105106
106107 favBook()
107108 // => get the state right now
109 +
110 +```
111 +
112 +state has form:
113 +```js
108114 // {
109115 // key: '%A4RPANAIiCtO9phwbL0tqk9ta4ltzzZwECZjsH25rqY=.sha256',
110116 // value: { }, // the original message content
111117 // attributes: { }, // contains the single 'winning' state for each attr
@@ -113,9 +119,9 @@
113119 // latestAttributes: { } // the latest state of each attribute from each peer
114120 // }
115121 ```
116122
117-`attributes`:
123 +where `attributes` and `latestAttributes`:
118124 ```js
119125 {
120126 title: String,
121127 authors: String | Array,
@@ -131,9 +137,9 @@
131137 genre
132138 }
133139 ```
134140
135-### `book.async.get(id, cb)`
141 +### `book.async.get(key, cb)`
136142
137143 Similar to `book.obs.get` but an asynchronous method for e.g. backend rendering.
138144
139145 ### `book.obs.shelves()`
@@ -186,4 +192,12 @@
186192 text: String,
187193 branch: String | Array
188194 }
189195 ```
196 +
197 +## Development
198 +
199 +Run the tests with `npm test`
200 +
201 +Some tests require an sbot to be running and currently use your personal identity to read real books.
202 +TODO - build a test harness with an in-memory db.
203 +
async/comment.jsView
@@ -1,5 +1,5 @@
1-module.exports = function (client) {
1 +module.exports = function (server) {
22 return function (id, text, cb) {
33 // lookup the book and existing messages attached (just comments?)
44 // calculate the correct branch (using ssb-sort ?)
55
async/create.jsView
@@ -1,11 +1,11 @@
11 const isBook = require('../sync/isBook')()
2-// isBook is an odd case that doesn't need a client
2 +// isBook is an odd case that doesn't need a server
33
4-module.exports = function (client) {
4 +module.exports = function (server) {
55 return function (book, cb) {
66 if (!isBook(book)) return cb(isBook.errors)
77
8- client.publish(book, cb)
8 + server.publish(book, cb)
99 }
1010 }
1111
async/isBookComment.jsView
@@ -1,5 +1,5 @@
11 const validator = require('is-my-json-valid')
2-const schema = require('../schemas/bookComment')
2 +const schema = require('../schema/bookComment')
33
44 module.exports = validator(schema)
55
async/isBookUpdate.jsView
@@ -1,5 +1,5 @@
11 const validator = require('is-my-json-valid')
2-const schema = require('../schemas/bookUpdate')
2 +const schema = require('../schema/bookUpdate')
33
44 module.exports = validator(schema)
55
index.jsView
@@ -5,16 +5,17 @@
55 // comment: require('./async/comment'),
66 create: require('./async/create'),
77 // get: require('./async/get'),
88 // isBookComment: require('./async/isBookComment'),
9 + // isBookKey: require('./async/isBookKey'),
910 // isBookUpdate: require('./async/isBookUpdate'),
1011 // update: require('./async/update'),
1112 },
12- // obs: {
13- // authors: require('./obs/authors'),
14- // book: require('./obs/book'),
15- // shelves: require('./obs/shelves'),
16- // },
13 + obs: {
14 + // authors: require('./obs/authors'),
15 + get: require('./obs/get'),
16 + // shelves: require('./obs/shelves'),
17 + },
1718 // pull: {
1819 // books: require('./pull/books'),
1920 // comments: require('./pull/comments'),
2021 // updates: require('./pull/updates'),
obs/book.jsView
obs/get.jsView
@@ -1,0 +1,64 @@
1 +const { Struct, Value, Array: MutantArray, Dict } = require('mutant')
2 +const { isBlob } = require('ssb-ref')
3 +
4 +function Book (key) {
5 + return Struct({
6 + key,
7 + value: Value(),
8 + latestAttributes: Dict(), // attributes according to each user
9 + errors: MutantArray (),
10 + sync: false
11 + })
12 +}
13 +
14 +module.exports = function (server) {
15 + return function (key) {
16 +
17 + // TODO take key or msg?
18 +
19 + const book = Book(key)
20 + server.get(key, (err, msgVal) => {
21 + if (err) return book.errors.push(err)
22 +
23 + // TODO run isBook?
24 + book.value.set(msgVal)
25 + updateLatestAttributes(book, msgVal)
26 +
27 + // TODO figure out where to put this
28 + book.sync.set(true)
29 + })
30 +
31 + return book
32 + }
33 +}
34 +
35 +function updateLatestAttributes (book, msgVal) {
36 + // TODO check isBook / isBookUpdate?
37 + const { author: user, content } = msgVal
38 +
39 + prune(content)
40 + normalizeImages(content)
41 +
42 + const currentAttributes = book.latestAttributes.get(user) || {}
43 + const latestAttributes = Object.assign({}, currentAttributes, content)
44 +
45 + book.latestAttributes.put(user, latestAttributes)
46 +}
47 +
48 +function prune (content) {
49 + // prune attributes we don't want in the final attributes
50 + delete content.type
51 + delete content.about
52 +}
53 +
54 +function normalizeImages (content) {
55 + if (!content.image) return
56 +
57 + var blob
58 + if (typeof content.image === 'string') blob = content.image
59 + if (content.image && content.image.link) blob = content.image.link
60 +
61 + if (!isBlob(blob)) return delete content.image
62 +
63 + content.image = blob
64 +}
package-lock.jsonView
@@ -31,8 +31,13 @@
3131 "balanced-match": "1.0.0",
3232 "concat-map": "0.0.1"
3333 }
3434 },
35 + "browser-split": {
36 + "version": "0.0.1",
37 + "resolved": "https://registry.npmjs.org/browser-split/-/browser-split-0.0.1.tgz",
38 + "integrity": "sha1-ewl1dPjj6tYG+0Zk5krf3aKYGpM="
39 + },
3540 "chalk": {
3641 "version": "1.1.3",
3742 "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
3843 "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
@@ -44,8 +49,30 @@
4449 "strip-ansi": "3.0.1",
4550 "supports-color": "2.0.0"
4651 }
4752 },
53 + "chloride": {
54 + "version": "2.2.8",
55 + "resolved": "https://registry.npmjs.org/chloride/-/chloride-2.2.8.tgz",
56 + "integrity": "sha1-6/mos8qJp0R8NgOW2t+BfIqY1Zk=",
57 + "dev": true,
58 + "requires": {
59 + "is-electron": "2.1.0",
60 + "sodium-browserify": "1.2.1",
61 + "sodium-browserify-tweetnacl": "0.2.3",
62 + "sodium-chloride": "1.1.0",
63 + "sodium-native": "2.1.3"
64 + }
65 + },
66 + "chloride-test": {
67 + "version": "1.2.2",
68 + "resolved": "https://registry.npmjs.org/chloride-test/-/chloride-test-1.2.2.tgz",
69 + "integrity": "sha1-F4aGqF6SeARREulujHkXk/mhCuo=",
70 + "dev": true,
71 + "requires": {
72 + "json-buffer": "2.0.11"
73 + }
74 + },
4875 "concat-map": {
4976 "version": "0.0.1",
5077 "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
5178 "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
@@ -62,8 +89,14 @@
6289 "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
6390 "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
6491 "dev": true
6592 },
93 + "deep-extend": {
94 + "version": "0.4.2",
95 + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
96 + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=",
97 + "dev": true
98 + },
6699 "define-properties": {
67100 "version": "1.1.2",
68101 "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
69102 "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
@@ -84,8 +117,17 @@
84117 "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
85118 "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
86119 "dev": true
87120 },
121 + "ed2curve": {
122 + "version": "0.1.4",
123 + "resolved": "https://registry.npmjs.org/ed2curve/-/ed2curve-0.1.4.tgz",
124 + "integrity": "sha1-lKRCSLuH2jXbDv968KpXYWgRf1k=",
125 + "dev": true,
126 + "requires": {
127 + "tweetnacl": "0.14.5"
128 + }
129 + },
88130 "es-abstract": {
89131 "version": "1.10.0",
90132 "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz",
91133 "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==",
@@ -114,8 +156,14 @@
114156 "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
115157 "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
116158 "dev": true
117159 },
160 + "explain-error": {
161 + "version": "1.0.4",
162 + "resolved": "https://registry.npmjs.org/explain-error/-/explain-error-1.0.4.tgz",
163 + "integrity": "sha1-p5PTrAytTGq1cemWj7urbLJTKSk=",
164 + "dev": true
165 + },
118166 "figures": {
119167 "version": "1.7.0",
120168 "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
121169 "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
@@ -196,8 +244,14 @@
196244 "requires": {
197245 "ansi-regex": "2.1.1"
198246 }
199247 },
248 + "increment-buffer": {
249 + "version": "1.0.1",
250 + "resolved": "https://registry.npmjs.org/increment-buffer/-/increment-buffer-1.0.1.tgz",
251 + "integrity": "sha1-ZQdtdRidgIs5rROrW5WOBSFvng0=",
252 + "dev": true
253 + },
200254 "inflight": {
201255 "version": "1.0.6",
202256 "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
203257 "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
@@ -212,8 +266,19 @@
212266 "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
213267 "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
214268 "dev": true
215269 },
270 + "ini": {
271 + "version": "1.3.5",
272 + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
273 + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
274 + "dev": true
275 + },
276 + "ip": {
277 + "version": "1.1.5",
278 + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
279 + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
280 + },
216281 "is-callable": {
217282 "version": "1.1.3",
218283 "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
219284 "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=",
@@ -224,8 +289,14 @@
224289 "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
225290 "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
226291 "dev": true
227292 },
293 + "is-electron": {
294 + "version": "2.1.0",
295 + "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.1.0.tgz",
296 + "integrity": "sha512-dkg5xT383+M6zIbbXW/z7n2nz4SFUi2OSyhntnFYkRdtV+HVEfdjEK+5AWisfYgkpe3WYjTIuh7toaKmSfFVWw==",
297 + "dev": true
298 + },
228299 "is-finite": {
229300 "version": "1.0.2",
230301 "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
231302 "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
@@ -270,25 +341,57 @@
270341 "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
271342 "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
272343 "dev": true
273344 },
345 + "is-valid-domain": {
346 + "version": "0.0.5",
347 + "resolved": "https://registry.npmjs.org/is-valid-domain/-/is-valid-domain-0.0.5.tgz",
348 + "integrity": "sha1-SOcDGfy0MAkjbpazf5hDiJzntRM="
349 + },
274350 "isarray": {
275351 "version": "1.0.0",
276352 "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
277353 "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
278354 "dev": true
279355 },
356 + "json-buffer": {
357 + "version": "2.0.11",
358 + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-2.0.11.tgz",
359 + "integrity": "sha1-PkQf2jCYvo0eMXGtWRvGKjPi1V8=",
360 + "dev": true
361 + },
280362 "jsonpointer": {
281363 "version": "4.0.1",
282364 "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
283365 "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk="
284366 },
367 + "libsodium": {
368 + "version": "0.2.12",
369 + "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.2.12.tgz",
370 + "integrity": "sha1-gwg1ZNzwicuCpQNb6Sul0iSizN4=",
371 + "dev": true
372 + },
373 + "libsodium-wrappers": {
374 + "version": "0.2.12",
375 + "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.2.12.tgz",
376 + "integrity": "sha1-UftQd0uO3FF5J7MHuBKkbDpGfh4=",
377 + "dev": true,
378 + "requires": {
379 + "libsodium": "0.2.12"
380 + }
381 + },
285382 "lodash": {
286383 "version": "3.10.1",
287384 "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
288385 "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
289386 "dev": true
290387 },
388 + "looper": {
389 + "version": "3.0.0",
390 + "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz",
391 + "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=",
392 + "dev": true
393 + },
291394 "minimatch": {
292395 "version": "3.0.4",
293396 "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
294397 "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
@@ -302,8 +405,99 @@
302405 "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
303406 "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
304407 "dev": true
305408 },
409 + "mkdirp": {
410 + "version": "0.5.1",
411 + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
412 + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
413 + "dev": true,
414 + "requires": {
415 + "minimist": "0.0.8"
416 + },
417 + "dependencies": {
418 + "minimist": {
419 + "version": "0.0.8",
420 + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
421 + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
422 + "dev": true
423 + }
424 + }
425 + },
426 + "multicb": {
427 + "version": "1.2.2",
428 + "resolved": "https://registry.npmjs.org/multicb/-/multicb-1.2.2.tgz",
429 + "integrity": "sha512-PZM4dhYFmCF6uZGWpEmoPMUqJBywS9IcAgybT2GmSpYI1BvGvoWSdbio+ik+q/YD2vodhvslESWIS3NnkKYdqQ==",
430 + "dev": true
431 + },
432 + "multiserver": {
433 + "version": "1.10.1",
434 + "resolved": "https://registry.npmjs.org/multiserver/-/multiserver-1.10.1.tgz",
435 + "integrity": "sha1-WiP57wpI9ldDEOCT4qos+lrrka0=",
436 + "dev": true,
437 + "requires": {
438 + "pull-cat": "1.1.11",
439 + "pull-stream": "3.6.1",
440 + "pull-ws": "3.3.0",
441 + "secret-handshake": "1.1.12",
442 + "separator-escape": "0.0.0",
443 + "socks": "1.1.9",
444 + "stream-to-pull-stream": "1.7.2"
445 + }
446 + },
447 + "mutant": {
448 + "version": "3.22.1",
449 + "resolved": "https://registry.npmjs.org/mutant/-/mutant-3.22.1.tgz",
450 + "integrity": "sha1-kEh1RvcAs8KKqApD0c99M48wdYE=",
451 + "requires": {
452 + "browser-split": "0.0.1",
453 + "xtend": "4.0.1"
454 + }
455 + },
456 + "muxrpc": {
457 + "version": "6.4.0",
458 + "resolved": "https://registry.npmjs.org/muxrpc/-/muxrpc-6.4.0.tgz",
459 + "integrity": "sha1-JPfaBpvUYpsHfpk7BXeUKyaI6ug=",
460 + "dev": true,
461 + "requires": {
462 + "explain-error": "1.0.4",
463 + "packet-stream": "2.0.2",
464 + "packet-stream-codec": "1.1.2",
465 + "pull-goodbye": "0.0.2",
466 + "pull-stream": "3.6.1"
467 + }
468 + },
469 + "nan": {
470 + "version": "2.8.0",
471 + "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
472 + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=",
473 + "dev": true,
474 + "optional": true
475 + },
476 + "node-gyp-build": {
477 + "version": "3.2.2",
478 + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.2.2.tgz",
479 + "integrity": "sha512-t8W/0UqFGl1c+5ORA3NoT3npU+PxWBL9iPhY7ZySSTszodj3RWexmu8niayWBE0v+0DLARvOXsjaAvfmSEQOyQ==",
480 + "dev": true,
481 + "optional": true
482 + },
483 + "non-private-ip": {
484 + "version": "1.4.2",
485 + "resolved": "https://registry.npmjs.org/non-private-ip/-/non-private-ip-1.4.2.tgz",
486 + "integrity": "sha1-7VH6e/fpGpxjI5TxBUe2o5Xovq0=",
487 + "dev": true,
488 + "requires": {
489 + "ip": "0.3.3"
490 + },
491 + "dependencies": {
492 + "ip": {
493 + "version": "0.3.3",
494 + "resolved": "https://registry.npmjs.org/ip/-/ip-0.3.3.tgz",
495 + "integrity": "sha1-jugwnpLwsEDSh/cu+soaIXAtP7Q=",
496 + "dev": true
497 + }
498 + }
499 + },
306500 "number-is-nan": {
307501 "version": "1.0.1",
308502 "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
309503 "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
@@ -335,8 +529,36 @@
335529 "requires": {
336530 "wrappy": "1.0.2"
337531 }
338532 },
533 + "options": {
534 + "version": "0.0.6",
535 + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
536 + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=",
537 + "dev": true
538 + },
539 + "os-homedir": {
540 + "version": "1.0.2",
541 + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
542 + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
543 + "dev": true
544 + },
545 + "packet-stream": {
546 + "version": "2.0.2",
547 + "resolved": "https://registry.npmjs.org/packet-stream/-/packet-stream-2.0.2.tgz",
548 + "integrity": "sha1-uQt/m6tKliQiy8nLJHGcNT5JMmc=",
549 + "dev": true
550 + },
551 + "packet-stream-codec": {
552 + "version": "1.1.2",
553 + "resolved": "https://registry.npmjs.org/packet-stream-codec/-/packet-stream-codec-1.1.2.tgz",
554 + "integrity": "sha1-ebMC/BRM37tKtv66cEDmpdmcecc=",
555 + "dev": true,
556 + "requires": {
557 + "pull-reader": "1.2.9",
558 + "pull-through": "1.0.18"
559 + }
560 + },
339561 "parse-ms": {
340562 "version": "1.0.1",
341563 "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz",
342564 "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=",
@@ -370,14 +592,134 @@
370592 "parse-ms": "1.0.1",
371593 "plur": "1.0.0"
372594 }
373595 },
596 + "private-box": {
597 + "version": "0.2.1",
598 + "resolved": "https://registry.npmjs.org/private-box/-/private-box-0.2.1.tgz",
599 + "integrity": "sha1-HfBhr8pbMDnH/qrdDa8PVvB+PsA=",
600 + "dev": true,
601 + "requires": {
602 + "chloride": "2.2.8"
603 + }
604 + },
374605 "process-nextick-args": {
375606 "version": "1.0.7",
376607 "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
377608 "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
378609 "dev": true
379610 },
611 + "pull-box-stream": {
612 + "version": "1.0.13",
613 + "resolved": "https://registry.npmjs.org/pull-box-stream/-/pull-box-stream-1.0.13.tgz",
614 + "integrity": "sha1-w+JAOY6rP1lRsu0QeMWYi/egork=",
615 + "dev": true,
616 + "requires": {
617 + "chloride": "2.2.8",
618 + "increment-buffer": "1.0.1",
619 + "pull-reader": "1.2.9",
620 + "pull-stream": "3.6.1",
621 + "pull-through": "1.0.18",
622 + "split-buffer": "1.0.0"
623 + }
624 + },
625 + "pull-cat": {
626 + "version": "1.1.11",
627 + "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz",
628 + "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=",
629 + "dev": true
630 + },
631 + "pull-goodbye": {
632 + "version": "0.0.2",
633 + "resolved": "https://registry.npmjs.org/pull-goodbye/-/pull-goodbye-0.0.2.tgz",
634 + "integrity": "sha1-jYNX21XiKnEN//DxaoyQtF7+QXE=",
635 + "dev": true,
636 + "requires": {
637 + "pull-stream": "3.5.0"
638 + },
639 + "dependencies": {
640 + "pull-stream": {
641 + "version": "3.5.0",
642 + "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.5.0.tgz",
643 + "integrity": "sha1-HuW292/Ts6SaWvtt7VwDIKyzz8c=",
644 + "dev": true
645 + }
646 + }
647 + },
648 + "pull-handshake": {
649 + "version": "1.1.4",
650 + "resolved": "https://registry.npmjs.org/pull-handshake/-/pull-handshake-1.1.4.tgz",
651 + "integrity": "sha1-YACg/QGIhM39c3JU+Mxgqypjd5E=",
652 + "dev": true,
653 + "requires": {
654 + "pull-cat": "1.1.11",
655 + "pull-pair": "1.1.0",
656 + "pull-pushable": "2.1.2",
657 + "pull-reader": "1.2.9"
658 + }
659 + },
660 + "pull-hash": {
661 + "version": "1.0.0",
662 + "resolved": "https://registry.npmjs.org/pull-hash/-/pull-hash-1.0.0.tgz",
663 + "integrity": "sha1-/K1NJQe/LCsyMfZT3Jv7LbTw2Iw=",
664 + "dev": true
665 + },
666 + "pull-pair": {
667 + "version": "1.1.0",
668 + "resolved": "https://registry.npmjs.org/pull-pair/-/pull-pair-1.1.0.tgz",
669 + "integrity": "sha1-fuQnJj/fTaglOXrAoF4atLdL120=",
670 + "dev": true
671 + },
672 + "pull-pushable": {
673 + "version": "2.1.2",
674 + "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.1.2.tgz",
675 + "integrity": "sha1-P+Fbj37sifOXLSOLwEiQyUBabbs=",
676 + "dev": true
677 + },
678 + "pull-reader": {
679 + "version": "1.2.9",
680 + "resolved": "https://registry.npmjs.org/pull-reader/-/pull-reader-1.2.9.tgz",
681 + "integrity": "sha1-0umtALz7VOYqpm1Cwtu8tetoQ7A=",
682 + "dev": true
683 + },
684 + "pull-stream": {
685 + "version": "3.6.1",
686 + "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.1.tgz",
687 + "integrity": "sha1-xcKuSlEkbv7rzGXAQSo9clqSzgA=",
688 + "dev": true
689 + },
690 + "pull-through": {
691 + "version": "1.0.18",
692 + "resolved": "https://registry.npmjs.org/pull-through/-/pull-through-1.0.18.tgz",
693 + "integrity": "sha1-jdYjFCY+Wc9Qlur7sSeitu8xBzU=",
694 + "dev": true,
695 + "requires": {
696 + "looper": "3.0.0"
697 + }
698 + },
699 + "pull-ws": {
700 + "version": "3.3.0",
701 + "resolved": "https://registry.npmjs.org/pull-ws/-/pull-ws-3.3.0.tgz",
702 + "integrity": "sha1-4cQ+9AMyFn3YEg71nt9+iSvqSq4=",
703 + "dev": true,
704 + "requires": {
705 + "relative-url": "1.0.2",
706 + "safe-buffer": "5.1.1",
707 + "ws": "1.1.5"
708 + }
709 + },
710 + "rc": {
711 + "version": "1.2.4",
712 + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.4.tgz",
713 + "integrity": "sha1-oPYGyq4qO4YrvQ74VILAElsxX6M=",
714 + "dev": true,
715 + "requires": {
716 + "deep-extend": "0.4.2",
717 + "ini": "1.3.5",
718 + "minimist": "1.2.0",
719 + "strip-json-comments": "2.0.1"
720 + }
721 + },
380722 "re-emitter": {
381723 "version": "1.1.3",
382724 "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.3.tgz",
383725 "integrity": "sha1-+p4xn/3u6zWycpbvDz03TawvUqc=",
@@ -397,8 +739,14 @@
397739 "string_decoder": "1.0.3",
398740 "util-deprecate": "1.0.2"
399741 }
400742 },
743 + "relative-url": {
744 + "version": "1.0.2",
745 + "resolved": "https://registry.npmjs.org/relative-url/-/relative-url-1.0.2.tgz",
746 + "integrity": "sha1-0hxSpy1gYQGLzun5yfwQa/fWUoc=",
747 + "dev": true
748 + },
401749 "repeat-string": {
402750 "version": "1.6.1",
403751 "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
404752 "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
@@ -427,8 +775,106 @@
427775 "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
428776 "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
429777 "dev": true
430778 },
779 + "secret-handshake": {
780 + "version": "1.1.12",
781 + "resolved": "https://registry.npmjs.org/secret-handshake/-/secret-handshake-1.1.12.tgz",
782 + "integrity": "sha512-5K2rx7QLBOz/JFAWGevU0JsoeC/0PZufSFJPqxQefZSdhMmB2aO16CJ9rwfnAzwMZMGrM+F2/ljXTP9wHp4GlA==",
783 + "dev": true,
784 + "requires": {
785 + "chloride": "2.2.8",
786 + "deep-equal": "1.0.1",
787 + "pull-box-stream": "1.0.13",
788 + "pull-handshake": "1.1.4",
789 + "pull-stream": "3.6.1"
790 + }
791 + },
792 + "separator-escape": {
793 + "version": "0.0.0",
794 + "resolved": "https://registry.npmjs.org/separator-escape/-/separator-escape-0.0.0.tgz",
795 + "integrity": "sha1-5DNnaTICBFTjwUhwxRfqHeVsL6Q=",
796 + "dev": true
797 + },
798 + "sha.js": {
799 + "version": "2.4.5",
800 + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.5.tgz",
801 + "integrity": "sha1-J9Fx78yCoRi5ljn/WBZgJCtQbnw=",
802 + "dev": true,
803 + "requires": {
804 + "inherits": "2.0.3"
805 + }
806 + },
807 + "smart-buffer": {
808 + "version": "1.1.15",
809 + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz",
810 + "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=",
811 + "dev": true
812 + },
813 + "socks": {
814 + "version": "1.1.9",
815 + "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.9.tgz",
816 + "integrity": "sha1-Yo1+TQSRJDVEWsC25Fk3bLPm1pE=",
817 + "dev": true,
818 + "requires": {
819 + "ip": "1.1.5",
820 + "smart-buffer": "1.1.15"
821 + }
822 + },
823 + "sodium-browserify": {
824 + "version": "1.2.1",
825 + "resolved": "https://registry.npmjs.org/sodium-browserify/-/sodium-browserify-1.2.1.tgz",
826 + "integrity": "sha1-sLVZyjaYFnkIUhSFXiZkXfZ6rxw=",
827 + "dev": true,
828 + "requires": {
829 + "libsodium-wrappers": "0.2.12",
830 + "sha.js": "2.4.5",
831 + "tweetnacl": "0.14.5"
832 + }
833 + },
834 + "sodium-browserify-tweetnacl": {
835 + "version": "0.2.3",
836 + "resolved": "https://registry.npmjs.org/sodium-browserify-tweetnacl/-/sodium-browserify-tweetnacl-0.2.3.tgz",
837 + "integrity": "sha1-tVN//LufdOvEQ7i2ohGykej8vI4=",
838 + "dev": true,
839 + "requires": {
840 + "chloride-test": "1.2.2",
841 + "ed2curve": "0.1.4",
842 + "sha.js": "2.4.10",
843 + "tweetnacl": "0.14.5",
844 + "tweetnacl-auth": "0.3.1"
845 + },
846 + "dependencies": {
847 + "sha.js": {
848 + "version": "2.4.10",
849 + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.10.tgz",
850 + "integrity": "sha512-vnwmrFDlOExK4Nm16J2KMWHLrp14lBrjxMxBJpu++EnsuBmpiYaM/MEs46Vxxm/4FvdP5yTwuCTO9it5FSjrqA==",
851 + "dev": true,
852 + "requires": {
853 + "inherits": "2.0.3",
854 + "safe-buffer": "5.1.1"
855 + }
856 + }
857 + }
858 + },
859 + "sodium-chloride": {
860 + "version": "1.1.0",
861 + "resolved": "https://registry.npmjs.org/sodium-chloride/-/sodium-chloride-1.1.0.tgz",
862 + "integrity": "sha1-JHojS4iGf23/UTMrYF8ZOmW/aDk=",
863 + "dev": true
864 + },
865 + "sodium-native": {
866 + "version": "2.1.3",
867 + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-2.1.3.tgz",
868 + "integrity": "sha512-BLZAiHgr1YPD+D50QpbaPGTNzEu5ozJjMgZhpjMJEijherL3u4vNAhgpRJX7Uuypfo9MCdbcB0fguXFijngWzg==",
869 + "dev": true,
870 + "optional": true,
871 + "requires": {
872 + "ini": "1.3.5",
873 + "nan": "2.8.0",
874 + "node-gyp-build": "3.2.2"
875 + }
876 + },
431877 "split": {
432878 "version": "1.0.1",
433879 "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
434880 "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
@@ -436,8 +882,72 @@
436882 "requires": {
437883 "through": "2.3.8"
438884 }
439885 },
886 + "split-buffer": {
887 + "version": "1.0.0",
888 + "resolved": "https://registry.npmjs.org/split-buffer/-/split-buffer-1.0.0.tgz",
889 + "integrity": "sha1-t+jgq1E0UVi3LB9tvvJAbVHx0Cc=",
890 + "dev": true
891 + },
892 + "ssb-client": {
893 + "version": "4.5.2",
894 + "resolved": "https://registry.npmjs.org/ssb-client/-/ssb-client-4.5.2.tgz",
895 + "integrity": "sha1-aBnyPwrBz/O6MfOsr0NAzG6SwZ8=",
896 + "dev": true,
897 + "requires": {
898 + "explain-error": "1.0.4",
899 + "multicb": "1.2.2",
900 + "multiserver": "1.10.1",
901 + "muxrpc": "6.4.0",
902 + "pull-hash": "1.0.0",
903 + "pull-stream": "3.6.1",
904 + "ssb-config": "2.2.0",
905 + "ssb-keys": "7.0.13"
906 + }
907 + },
908 + "ssb-config": {
909 + "version": "2.2.0",
910 + "resolved": "https://registry.npmjs.org/ssb-config/-/ssb-config-2.2.0.tgz",
911 + "integrity": "sha1-QcrQOKhXWvQGLT/VfTsWe+hbA7w=",
912 + "dev": true,
913 + "requires": {
914 + "deep-extend": "0.4.2",
915 + "non-private-ip": "1.4.2",
916 + "os-homedir": "1.0.2",
917 + "rc": "1.2.4"
918 + }
919 + },
920 + "ssb-keys": {
921 + "version": "7.0.13",
922 + "resolved": "https://registry.npmjs.org/ssb-keys/-/ssb-keys-7.0.13.tgz",
923 + "integrity": "sha1-nWUnEAWHawfOqie3JICPDGAQu8k=",
924 + "dev": true,
925 + "requires": {
926 + "chloride": "2.2.8",
927 + "mkdirp": "0.5.1",
928 + "private-box": "0.2.1"
929 + }
930 + },
931 + "ssb-ref": {
932 + "version": "2.9.1",
933 + "resolved": "https://registry.npmjs.org/ssb-ref/-/ssb-ref-2.9.1.tgz",
934 + "integrity": "sha1-YIYXE9gMERqaUq6DCZ4zGvzbv2s=",
935 + "requires": {
936 + "ip": "1.1.5",
937 + "is-valid-domain": "0.0.5"
938 + }
939 + },
940 + "stream-to-pull-stream": {
941 + "version": "1.7.2",
942 + "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.2.tgz",
943 + "integrity": "sha1-dXYJrhzr0zx0MtSvvjH/eGULnd4=",
944 + "dev": true,
945 + "requires": {
946 + "looper": "3.0.0",
947 + "pull-stream": "3.6.1"
948 + }
949 + },
440950 "string.prototype.trim": {
441951 "version": "1.1.2",
442952 "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz",
443953 "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=",
@@ -465,8 +975,14 @@
465975 "requires": {
466976 "ansi-regex": "2.1.1"
467977 }
468978 },
979 + "strip-json-comments": {
980 + "version": "2.0.1",
981 + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
982 + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
983 + "dev": true
984 + },
469985 "supports-color": {
470986 "version": "2.0.0",
471987 "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
472988 "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
@@ -542,8 +1058,29 @@
5421058 "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
5431059 "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=",
5441060 "dev": true
5451061 },
1062 + "tweetnacl": {
1063 + "version": "0.14.5",
1064 + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
1065 + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
1066 + "dev": true
1067 + },
1068 + "tweetnacl-auth": {
1069 + "version": "0.3.1",
1070 + "resolved": "https://registry.npmjs.org/tweetnacl-auth/-/tweetnacl-auth-0.3.1.tgz",
1071 + "integrity": "sha1-t1vC3xVkm7hOi5qjwGacbEvODSU=",
1072 + "dev": true,
1073 + "requires": {
1074 + "tweetnacl": "0.14.5"
1075 + }
1076 + },
1077 + "ultron": {
1078 + "version": "1.0.2",
1079 + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
1080 + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=",
1081 + "dev": true
1082 + },
5461083 "util-deprecate": {
5471084 "version": "1.0.2",
5481085 "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
5491086 "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
@@ -554,8 +1091,18 @@
5541091 "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
5551092 "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
5561093 "dev": true
5571094 },
1095 + "ws": {
1096 + "version": "1.1.5",
1097 + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz",
1098 + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==",
1099 + "dev": true,
1100 + "requires": {
1101 + "options": "0.0.6",
1102 + "ultron": "1.0.2"
1103 + }
1104 + },
5581105 "xtend": {
5591106 "version": "4.0.1",
5601107 "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
5611108 "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
package.jsonView
@@ -20,11 +20,14 @@
2020 "url": "https://github.com/mixmix/scuttle-book/issues"
2121 },
2222 "homepage": "https://github.com/mixmix/scuttle-book#readme",
2323 "dependencies": {
24- "is-my-json-valid": "^2.17.1"
24 + "is-my-json-valid": "^2.17.1",
25 + "mutant": "^3.22.1",
26 + "ssb-ref": "^2.9.1"
2527 },
2628 "devDependencies": {
29 + "ssb-client": "^4.5.2",
2730 "tap-spec": "^4.1.1",
2831 "tape": "^4.8.0"
2932 }
3033 }
sync/isBook.jsView
@@ -1,9 +1,9 @@
11 const validator = require('is-my-json-valid')
2-const schema = require('../schemas/book')
2 +const schema = require('../schema/book')
33
4-// client is not used here. Closure pattern is just for consistency of use with other functions.
5-module.exports = function (client) {
4 +// server is not used here. Closure pattern is just for consistency of use with other functions.
5 +module.exports = function (server) {
66 const isBookContent = validator(schema, {verbose: true})
77
88 return function isBook (obj) {
99 const result = isBookContent(getMsgContent(obj))
tests/isBook.jsView
@@ -1,31 +1,0 @@
1-const test = require('tape')
2-const validator = require('is-my-json-valid')
3-
4-const isBook = require('../isBook.js')
5-
6-test('isBoot / book schema', t => {
7-
8- const simpleBook = {
9- type: 'bookclub',
10- authors: 'Ursula le Guin',
11- title: 'The Dispossessed'
12- }
13- t.ok(isBook(simpleBook), 'validates simple book')
14-
15- const incompleteBook = {
16- type: 'bookclub',
17- authors: 'Ursula le Guin',
18- }
19- t.notOk(isBook(incompleteBook), 'invalidates incompleteBook book')
20- t.equal(isBook.errors[0].message, 'is required', 'provides error messages')
21-
22- const multiAuthorBook = {
23- type: 'bookclub',
24- authors: ['Ursula le Guin', 'Terry Pratchett'],
25- title: 'The Dispossessed'
26- }
27- t.ok(isBook(multiAuthorBook), 'validates multi-author book')
28-
29- t.end()
30-})
31-
tests/obs/get.jsView
@@ -1,0 +1,36 @@
1 +const test = require('tape')
2 +const Client = require('ssb-client')
3 +const { watch } = require('mutant')
4 +const { isBlob } = require('ssb-ref')
5 +const Get = require('../../obs/get')
6 +
7 +test('obs.get', t => {
8 + Client((err, server) => {
9 + if (err) throw err
10 +
11 + const get = Get(server)
12 +
13 + const key = '%0ANsrEUsgCEzA+mVHgFH+oX2aHa3vHdSSIqW27moJNk=.sha256'
14 + const postedBy = '@ye+QM09iPcDJD6YvQYjoQc7sLF/IFhmNbEqgdzQo3lQ=.ed25519'
15 + // The Dispossessed, posted by mix : @ye+QM09iPcDJD6YvQYjoQc7sLF/IFhmNbEqgdzQo3lQ=.ed25519
16 +
17 + const book = get(key)
18 +
19 + // book(state => console.log('***UPDATE***', '\n', state, '\n', '\n'))
20 +
21 + watch(book.sync, (done) => {
22 + if (!done) return
23 +
24 + const myAttributes = book.latestAttributes.get(postedBy)
25 + t.equal(myAttributes.authors, 'Ursula Le Guin', "collects mix's opinion about author")
26 + t.equal(myAttributes.title, 'The Disposessed', "collects mix's opinion about title")
27 + t.ok(isBlob(myAttributes.image), "collects mix's opinion about image")
28 +
29 + server.close()
30 + t.end()
31 + })
32 + })
33 +
34 +})
35 +
36 +
tests/sync/isBook.jsView
@@ -1,0 +1,32 @@
1 +const test = require('tape')
2 +const validator = require('is-my-json-valid')
3 +
4 +const isBook = require('../../sync/isBook')()
5 +// or const isBook = require('../../isBook')
6 +
7 +test('isBoot / book schema', t => {
8 +
9 + const simpleBook = {
10 + type: 'bookclub',
11 + authors: 'Ursula le Guin',
12 + title: 'The Dispossessed'
13 + }
14 + t.ok(isBook(simpleBook), 'validates simple book')
15 +
16 + const incompleteBook = {
17 + type: 'bookclub',
18 + authors: 'Ursula le Guin',
19 + }
20 + t.notOk(isBook(incompleteBook), 'invalidates incompleteBook book')
21 + t.equal(isBook.errors[0].message, 'is required', 'provides error messages')
22 +
23 + const multiAuthorBook = {
24 + type: 'bookclub',
25 + authors: ['Ursula le Guin', 'Terry Pratchett'],
26 + title: 'The Dispossessed'
27 + }
28 + t.ok(isBook(multiAuthorBook), 'validates multi-author book')
29 +
30 + t.end()
31 +})
32 +
schemas/book.jsView
@@ -1,18 +1,0 @@
1-module.exports = {
2- $schema: 'http://json-schema.org/schema#',
3- type: 'object',
4- required: ['type', 'title', 'authors'],
5- properties: {
6- type: {type: 'string', pattern: 'bookclub'},
7- title: {type: 'string'},
8- authors: {
9- oneOf: [
10- {type: 'string'},
11- {type: 'array', items: {allOf: [{type: 'string'}]
12- }}
13- ]
14- }
15- // TODO add other fields
16- }
17-}
18-
schemas/bookComment.jsView
schemas/bookUpdate.jsView
schema/book.jsView
@@ -1,0 +1,18 @@
1 +module.exports = {
2 + $schema: 'http://json-schema.org/schema#',
3 + type: 'object',
4 + required: ['type', 'title', 'authors'],
5 + properties: {
6 + type: {type: 'string', pattern: 'bookclub'},
7 + title: {type: 'string'},
8 + authors: {
9 + oneOf: [
10 + {type: 'string'},
11 + {type: 'array', items: {allOf: [{type: 'string'}]
12 + }}
13 + ]
14 + }
15 + // TODO add other fields
16 + }
17 +}
18 +
schema/bookComment.jsView
schema/bookUpdate.jsView

Built with git-ssb-web