Browse Source

init command schemas

Kieran Gibb 2 years ago
commit
4f7b13413e
No known key found for this signature in database

+ 16
- 0
README.md View File

@@ -0,0 +1,16 @@
1
+# cobox-command-schemas
2
+
3
+A set of message schemas for sending commands to and from your cobox device from an admin client device.
4
+
5
+## Examples
6
+
7
+```js
8
+// schemas/broadcast
9
+{
10
+  type: "broadcast",
11
+  timestamp: 1575367024623,
12
+  content: {
13
+    command: "start",
14
+  }
15
+}
16
+```

+ 23
- 0
index.js View File

@@ -0,0 +1,23 @@
1
+const Validator = require('is-my-json-valid')
2
+const schemas = require('./schemas')
3
+
4
+module.exports = {
5
+  schema: validator(schemas.schema),
6
+  commands: {
7
+    broadcast: {
8
+      start: validator(schemas.commands.broadcast.start),
9
+      stop: validator(schemas.commands.broadcast.stop)
10
+    }
11
+  }
12
+}
13
+
14
+function validator (schema) {
15
+  var validate = Validator(schema)
16
+
17
+  return function isValid (msg, opts = {}) {
18
+    const result = validate(msg)
19
+    isValid.errors = validate.errors
20
+    if (opts.attachErrors) msg.errors = isValid.errors
21
+    return result
22
+  }
23
+}

+ 35
- 0
package.json View File

@@ -0,0 +1,35 @@
1
+{
2
+  "name": "cobox-command-schemas",
3
+  "version": "1.0.0",
4
+  "description": "command message schemas to execute actions between cobox device and admin client",
5
+  "main": "index.js",
6
+  "scripts": {
7
+    "test": "tape test/**/*.test.js | tap-spec"
8
+  },
9
+  "repository": {
10
+    "type": "git",
11
+    "url": "https://ledger-git.dyne.org/cobox/cobox-command-schemas"
12
+  },
13
+  "keywords": [
14
+    "cobox",
15
+    "hub",
16
+    "commands",
17
+    "admin"
18
+  ],
19
+  "author": "magma collective",
20
+  "license": "AGPL-3.0-or-later",
21
+  "dependencies": {
22
+    "is-my-json-valid": "^2.20.0"
23
+  },
24
+  "devDependencies": {
25
+    "cobox-crypto": "git+https://ledger-git.dyne.org/cobox/cobox-crypto#development",
26
+    "debug": "^4.1.1",
27
+    "mkdirp": "^0.5.1",
28
+    "nyc": "^14.1.1",
29
+    "rimraf": "^3.0.0",
30
+    "tap-spec": "^5.0.0",
31
+    "tape": "^4.11.0",
32
+    "tape-plus": "^1.0.0",
33
+    "tmp": "^0.1.0"
34
+  }
35
+}

+ 4
- 0
schemas/commands/broadcast/index.js View File

@@ -0,0 +1,4 @@
1
+module.exports = {
2
+  start: require('./start'),
3
+  stop: require('./stop')
4
+}

+ 19
- 0
schemas/commands/broadcast/start.js View File

@@ -0,0 +1,19 @@
1
+var baseSchema = require('../../schema')
2
+
3
+module.exports = Object.assign({}, baseSchema, {
4
+  required: [...baseSchema.required, 'content'],
5
+  properties: {
6
+    type: {
7
+      type: 'string',
8
+      pattern: '^broadcast'
9
+    },
10
+    content: {
11
+      type: 'object',
12
+      required: ['command'],
13
+      command: {
14
+        type: 'string',
15
+        pattern: '^start$'
16
+      }
17
+    }
18
+  }
19
+})

+ 19
- 0
schemas/commands/broadcast/stop.js View File

@@ -0,0 +1,19 @@
1
+var baseSchema = require('../../schema')
2
+
3
+module.exports = Object.assign({}, baseSchema, {
4
+  required: [...baseSchema.required, 'content'],
5
+  properties: {
6
+    type: {
7
+      type: 'string',
8
+      pattern: '^broadcast'
9
+    },
10
+    content: {
11
+      type: 'object',
12
+      required: ['command'],
13
+      command: {
14
+        type: 'string',
15
+        pattern: '^stop$'
16
+      }
17
+    }
18
+  }
19
+})

+ 3
- 0
schemas/commands/index.js View File

@@ -0,0 +1,3 @@
1
+module.exports = {
2
+  broadcast: require('./broadcast')
3
+}

+ 4
- 0
schemas/index.js View File

@@ -0,0 +1,4 @@
1
+module.exports = {
2
+  schema: require('./schema'),
3
+  commands: require('./commands')
4
+}

+ 10
- 0
schemas/schema.js View File

@@ -0,0 +1,10 @@
1
+module.exports = {
2
+  $schema: 'http://json-schema.org/schema#',
3
+  type: 'object',
4
+  required: ['type', 'timestamp'],
5
+  properties: {
6
+    type: { type: 'string' },
7
+    timestamp: { type: 'integer' }
8
+  }
9
+}
10
+

+ 31
- 0
test/index.test.js View File

@@ -0,0 +1,31 @@
1
+const { describe } = require('tape-plus')
2
+const crypto = require('cobox-crypto')
3
+const schemas = require('../')
4
+
5
+const { tmp, cleanup } = require('./util')
6
+
7
+describe('broadcast', (context) => {
8
+  context('valid', async (assert, next) => {
9
+    var data = {
10
+      timestamp: Date.now(),
11
+      type: "broadcast",
12
+      content: { command: "start" }
13
+    }
14
+
15
+    var isValid = schemas.commands.broadcast.start(data)
16
+    assert.ok(isValid, 'data is valid')
17
+    next()
18
+  })
19
+
20
+  context('invalid', async (assert, next) => {
21
+    var data = {
22
+      timestamp: Date.now(),
23
+      type: "broadcast"
24
+    }
25
+
26
+    var isValid = schemas.commands.broadcast.start(data)
27
+    assert.notOk(isValid, 'data is not valid')
28
+    next()
29
+  })
30
+})
31
+

+ 63
- 0
test/util.js View File

@@ -0,0 +1,63 @@
1
+const rimraf = require('rimraf')
2
+const debug = require('debug')('cleanup')
3
+const tmpdir = require('tmp').dirSync
4
+const mkdirp = require('mkdirp')
5
+
6
+function cleanup (dirs, cb) {
7
+  if (!cb) cb = noop
8
+  if (!Array.isArray(dirs)) dirs = [dirs]
9
+  var pending = 1
10
+
11
+  function next (n) {
12
+    var dir = dirs[n]
13
+    if (!dir) return done()
14
+    ++pending
15
+    process.nextTick(next, n + 1)
16
+
17
+    rimraf(dir, (err) => {
18
+      if (err) return done(err)
19
+      done()
20
+    })
21
+  }
22
+
23
+  function done (err) {
24
+    if (err) {
25
+      pending = Infinity
26
+      return cb(err)
27
+    }
28
+    if (!--pending) return cb()
29
+  }
30
+
31
+  next(0)
32
+}
33
+
34
+function tmp () {
35
+  var path = '.'+tmpdir().name
36
+  mkdirp.sync(path)
37
+  return path
38
+}
39
+
40
+function replicate (a, b, opts, cb) {
41
+  if (typeof opts === 'function') return replicate(a, b, {}, opts)
42
+  if (!cb) cb = noop
43
+
44
+  var s = a.replicate(true, Object.assign({ live: false }, opts))
45
+  var d = b.replicate(false, Object.assign({ live: false }, opts))
46
+
47
+  s.pipe(d).pipe(s)
48
+
49
+  s.on('error', (err) => {
50
+    if (err) return cb(err)
51
+  })
52
+
53
+  s.on('end', cb)
54
+}
55
+
56
+function uniq (array) {
57
+  if (!Array.isArray(array)) array = [array]
58
+  return Array.from(new Set(array))
59
+}
60
+
61
+function noop () {}
62
+
63
+module.exports = { cleanup, tmp, replicate, uniq }

+ 1717
- 0
yarn.lock
File diff suppressed because it is too large
View File