├── .gitignore ├── .jshintrc ├── LICENSE ├── README.md ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | # Browserify bundle 30 | bundle.js 31 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "browserify": true, 3 | "undef": true, 4 | "devel": true, 5 | "globalstrict": true, 6 | "validthis": true 7 | } 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, RangerMauve 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gun-schema 2 | Validate [Gun](http://gun.js.org/) data with JSON-Schema. 3 | 4 | Validation is done by [is-my-json-valid](https://github.com/mafintosh/is-my-json-valid) 5 | 6 | ## Getting started 7 | ### Browser 8 | Download the js bundle from the [releases page](https://github.com/gundb/gun-schema/releases) and add it to the page. As well as attaching the required methods to Gun, it will create a GunSchema global. 9 | 10 | ### Server 11 | Install from NPM 12 | 13 | ```bash 14 | npm install --save gun-schema 15 | ``` 16 | 17 | Require the module to have it attach itself to GUN 18 | 19 | ```JavaScript 20 | var Gun = require("gun"); 21 | require("gun-schema"); 22 | ``` 23 | 24 | ### Example 25 | 26 | ```JavaScript 27 | // Get a reference to your schema from wherever 28 | // This one was taken from the is-my-json-valid page 29 | var schema = { 30 | required: true, 31 | type: 'object', 32 | properties: { 33 | hello: { 34 | required: true, 35 | type: 'string' 36 | } 37 | } 38 | }; 39 | 40 | var gun = Gun(); 41 | 42 | gun.schema("example", schema); 43 | 44 | // This is valid so it'll get put into the graph 45 | gun.save("example", { 46 | hello: "World!" 47 | }); 48 | 49 | // This will throw an error because `hello` was set as `required` 50 | gun.save("example", { 51 | goodbye: "World!" 52 | }); 53 | ``` 54 | 55 | ## API 56 | After the plugin has been properly initialized, it adds the following methods on gun instances 57 | 58 | ### `gun.schema(name, schema, options)` 59 | Adds a new type that will be recognized by `gun.save()` 60 | - `name` : The unique name for this type of node 61 | - `schema` : The JSON Schema definition to use for validating this type 62 | - `options` : Optional argument which gets passed down to [is-my-json-valid](https://github.com/mafintosh/is-my-json-valid) 63 | 64 | ### `gun.schemas(map, options)` 65 | Adds a bunch of schemas in one go. 66 | - `map` : A map of `name`-`schema` pairs that get passed on to `gun.schema()` 67 | - `options` : Optional argument which gets passed down to `gun.schema()` to configure [is-my-json-valid](https://github.com/mafintosh/is-my-json-valid) 68 | 69 | ### `gun.save(name, value)` 70 | Similar to `gun.put()`, but uses the schema associated with `name` to ensure that `value` is valid. 71 | - `name` : The name of the schema that `value` should match 72 | - `value` : The value that should be validated before being `put()` into the DB. 73 | 74 | If `name` does not point to a schema name that has been registered, then an error will be thrown. If `value` doesn't validate against the schema, then an error will be thrown with a `errors` property which contains the list of things that are wrong with `value`. 75 | 76 | ### `GunSchema(gun)` 77 | This is what gets exported by the module in CommonJS and what is added as the `GunSchema` global in the bundle. It takes a gun instance and adds schema functionality to it. 78 | - `gun` The gun instance to attach to. Not, this isn't the `Gun` constructor, but an actual instance or `Gun.chain`. 79 | 80 | ## Building 81 | You can build the browser bundle yourself by cloning the repo and executing: 82 | 83 | ```bash 84 | `npm install` 85 | `npm install gun` 86 | `npm run bundle` 87 | ``` 88 | 89 | You will then have a file called `bundle.js` which you can embed in a webpage. The building is facilitated by [Browserify](http://browserify.org/) 90 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var globalVar = require("global"); 3 | var makeValidator = require("is-my-json-valid"); 4 | var Gun = globalVar.Gun || require("gun"); 5 | 6 | module.exports = makeSchema; 7 | 8 | if (!Gun) 9 | throw new Error("gun-schema: Gun was not found globally or via the bundle!"); 10 | 11 | makeSchema(Gun.chain); 12 | 13 | function makeSchema(gun) { 14 | gun.schema = addSchema; 15 | gun.schemas = addSchemas; 16 | gun.save = putValid; 17 | } 18 | 19 | function addSchemas(map, options) { 20 | var gun = this; 21 | 22 | var schemas = getSchemas(gun); 23 | 24 | for (var key in schemas) { 25 | var schema = schemas[key]; 26 | gun.schema(key, schema, options); 27 | } 28 | 29 | return gun; 30 | } 31 | 32 | function addSchema(name, schema, options) { 33 | var gun = this; 34 | 35 | var schemas = getSchemas(gun); 36 | 37 | var validate = makeValidator(schema, options); 38 | 39 | schemas[name] = validate; 40 | 41 | return gun; 42 | } 43 | 44 | function putValid(name, value) { 45 | var gun = this; 46 | 47 | var schemas = getSchemas(gun); 48 | 49 | var validate = schemas[name]; 50 | 51 | if (!validate) 52 | throw new TypeError(name + " has not been registered as a type"); 53 | 54 | var valid = validate(value); 55 | 56 | if (valid) 57 | return gun.put(value); 58 | 59 | var err = new TypeError("Value doesn't match schema for " + name); 60 | err.errors = validate.errors; 61 | throw err; 62 | } 63 | 64 | function getSchemas(gun) { 65 | if (!gun._schemas) 66 | gun._schemas = {}; 67 | return gun._schemas; 68 | } 69 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gun-schema", 3 | "version": "0.1.0", 4 | "description": "Validate GUN DB data with JSON-Schema", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "bundle": "browserify index.js --standalone GunSchema > bundle.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/RangerMauve/gun-schema.git" 13 | }, 14 | "keywords": [ 15 | "gun", 16 | "db", 17 | "json", 18 | "schema", 19 | "model", 20 | "graph" 21 | ], 22 | "author": "rangermauve", 23 | "license": "ISC", 24 | "bugs": { 25 | "url": "https://github.com/RangerMauve/gun-schema/issues" 26 | }, 27 | "homepage": "https://github.com/RangerMauve/gun-schema", 28 | "devDependencies": { 29 | "browserify": "^11.2.0" 30 | }, 31 | "peerDependencies": { 32 | "gun": "^0.2.x" 33 | }, 34 | "dependencies": { 35 | "global": "^4.3.0", 36 | "is-my-json-valid": "^2.12.2" 37 | }, 38 | "browser": { 39 | "gun": false 40 | } 41 | } 42 | --------------------------------------------------------------------------------