source: Dev/trunk/src/node_modules/tv4/README.md @ 519

Last change on this file since 519 was 487, checked in by hendrikvanantwerpen, 11 years ago

Completed migration to API, without CouchDB proxy.

Move to API is now completed. The full API is password protected, a very
limited API is exposed for respondents, which works with secrets that
are passed in URLs.

Serverside the HTTPResult class was introduced, which is similar to
Promises, but specifically for HTTP. It carries a status code and
response and makes it easier to extract parts of async handling in
separate functions.

Fixed a bug in our schema (it seems optional attributes don't exist but
a required list does). Verification of our schema by grunt-tv4 didn't
work yet. Our schema is organized the wrong way (this is fixable),
but the json-schema schema has problems with simple types and $refs.

File size: 11.2 KB
Line 
1# Tiny Validator (for v4 JSON Schema)
2
3[![Build Status](https://secure.travis-ci.org/geraintluff/tv4.png?branch=master)](http://travis-ci.org/geraintluff/tv4) [![Dependency Status](https://gemnasium.com/geraintluff/tv4.png)](https://gemnasium.com/geraintluff/tv4) [![NPM version](https://badge.fury.io/js/tv4.png)](http://badge.fury.io/js/tv4)
4
5Use [json-schema](http://json-schema.org/) [draft v4](http://json-schema.org/latest/json-schema-core.html) to validate simple values and complex objects using a rich [validation vocabulary](http://json-schema.org/latest/json-schema-validation.html) ([examples](http://json-schema.org/examples.html)).
6
7There is support for `$ref` with JSON Pointer fragment paths (```other-schema.json#/properties/myKey```).
8
9## Usage 1: Simple validation
10
11```javascript
12var valid = tv4.validate(data, schema);
13```
14
15If validation returns ```false```, then an explanation of why validation failed can be found in ```tv4.error```.
16
17The error object will look something like:
18```json
19{
20    "code": 0,
21    "message": "Invalid type: string",
22    "dataPath": "/intKey",
23    "schemaKey": "/properties/intKey/type"
24}
25```
26
27The `"code"` property will refer to one of the values in `tv4.errorCodes` - in this case, `tv4.errorCodes.INVALID_TYPE`.
28
29To enable external schema to be referenced, you use:
30```javascript
31tv4.addSchema(url, schema);
32```
33
34If schemas are referenced (```$ref```) but not known, then validation will return ```true``` and the missing schema(s) will be listed in ```tv4.missing```. For more info see the API documentation below.
35
36## Usage 2: Multi-threaded validation
37
38Storing the error and missing schemas does not work well in multi-threaded environments, so there is an alternative syntax:
39
40```javascript
41var result = tv4.validateResult(data, schema);
42```
43
44The result will look something like:
45```json
46{
47    "valid": false,
48    "error": {...},
49    "missing": [...]
50}
51```
52
53## Usage 3: Multiple errors
54
55Normally, `tv4` stops when it encounters the first validation error.  However, you can collect an array of validation errors using:
56
57```javascript
58var result = tv4.validateMultiple(data, schema);
59```
60
61The result will look something like:
62```json
63{
64    "valid": false,
65    "errors": [
66        {...},
67        ...
68    ],
69    "missing": [...]
70}
71```
72
73## Asynchronous validation
74
75Support for asynchronous validation (where missing schemas are fetched) can be added by including an extra JavaScript file.  Currently, the only version requires jQuery (`tv4.async-jquery.js`), but the code is very short and should be fairly easy to modify for other libraries (such as MooTools).
76
77Usage:
78
79```javascript
80tv4.validate(data, schema, function (isValid, validationError) { ... });
81```
82
83`validationFailure` is simply taken from `tv4.error`.
84
85## Cyclical JavaScript objects
86
87While they don't occur in proper JSON, JavaScript does support self-referencing objects. Any of the above calls support an optional third argument: `checkRecursive`. If true, tv4 will handle self-referencing objects properly - this slows down validation slightly, but that's better than a hanging script.
88
89Consider this data, notice how both `a` and `b` refer to each other:
90
91```javascript
92var a = {};
93var b = { a: a };
94a.b = b;
95var aSchema = { properties: { b: { $ref: 'bSchema' }}};
96var bSchema = { properties: { a: { $ref: 'aSchema' }}};
97tv4.addSchema('aSchema', aSchema);
98tv4.addSchema('bSchema', bSchema);
99```
100
101If the `checkRecursive` argument were missing, this would throw a "too much recursion" error.
102
103To enable support for this, pass `true` as additional argument to any of the regular validation methods:
104
105```javascript
106tv4.validate(a, aSchema, true);
107tv4.validateResult(data, aSchema, true);
108tv4.validateMultiple(data, aSchema, true);
109```
110
111## The `banUnknownProperties` flag
112
113Sometimes, it is desirable to flag all unknown properties as an error.  This is especially useful during development, to catch typos and the like, even when extra custom-defined properties are allowed.
114
115As such, tv4 implements ["ban unknown properties" mode](https://github.com/json-schema/json-schema/wiki/ban-unknown-properties-mode-\(v5-proposal\)), enabled by a fourth-argument flag:
116
117```javascript
118tv4.validate(data, schema, checkRecursive, true);
119tv4.validateResult(data, schema, checkRecursive, true);
120tv4.validateMultiple(data, schema, checkRecursive, true);
121```
122
123## API
124
125There are additional api commands available for more complex use-cases:
126
127##### addSchema(uri, schema)
128Pre-register a schema for reference by other schema and synchronous validation.
129
130````js
131tv4.addSchema('http://example.com/schema', { ... });
132````
133
134* `uri` the uri to identify this schema.
135* `schema` the schema object.
136
137Schemas that have their `id` property set can be added directly.
138
139````js
140tv4.addSchema({ ... });
141````
142
143##### getSchema(uri)
144
145Return a schema from the cache.
146
147* `uri` the uri of the schema (may contain a `#` fragment)
148
149````js
150var schema = tv4.getSchema('http://example.com/schema');
151````
152
153##### getSchemaMap()
154
155Return a shallow copy of the schema cache, mapping schema document URIs to schema objects.
156
157````
158var map = tv4.getSchemaMap();
159
160var schema = map[uri];
161````
162
163##### getSchemaUris(filter)
164
165Return an Array with known schema document URIs.
166
167* `filter` optional RegExp to filter URIs
168
169````
170var arr = tv4.getSchemaUris();
171
172// optional filter using a RegExp
173var arr = tv4.getSchemaUris(/^https?://example.com/);
174````
175
176##### getMissingUris(filter)
177
178Return an Array with schema document URIs that are used as `$ref` in known schemas but which currently have no associated schema data.
179
180Use this in combination with `tv4.addSchema(uri, schema)` to preload the cache for complete synchronous validation with.
181
182* `filter` optional RegExp to filter URIs
183
184````
185var arr = tv4.getMissingUris();
186
187// optional filter using a RegExp
188var arr = tv4.getMissingUris(/^https?://example.com/);
189````
190
191##### dropSchemas()
192
193Drop all known schema document URIs from the cache.
194
195````
196tv4.dropSchemas();
197````
198
199##### freshApi()
200
201Return a new tv4 instance with no shared state.
202
203````
204var otherTV4 = tv4.freshApi();
205````
206
207##### reset()
208
209Manually reset validation status from the simple `tv4.validate(data, schema)`. Although tv4 will self reset on each validation there are some implementation scenarios where this is useful.
210
211````
212tv4.reset();
213````
214
215##### language(code)
216
217Select the language map used for reporting.
218
219* `code` is a language code, like `'en'` or `'en-gb'`
220
221````
222tv4.language('en-gb');
223````
224
225##### addLanguage(code, map)
226
227Add a new language map for selection by `tv4.language(code)`
228
229* `code` is new language code
230* `map` is an object mapping error IDs or constant names (e.g. `103` or `"NUMBER_MAXIMUM"`) to language strings.
231
232````
233tv4.addLanguage('fr', { ... });
234
235// select for use
236tv4.language('fr')
237````
238
239##### addFormat(format, validationFunction)
240
241Add a custom format validator. (There are no built-in format validators.)
242
243* `format` is a string, corresponding to the `"format"` value in schemas.
244* `validationFunction` is a function that either returns:
245  * `null` (meaning no error)
246  * an error string (explaining the reason for failure)
247
248````
249tv4.addFormat('decimal-digits', function (data, schema) {
250        if (typeof data === 'string' && !/^[0-9]+$/.test(data)) {
251                return null;
252        }
253        return "must be string of decimal digits";
254});
255````
256
257Alternatively, multiple formats can be added at the same time using an object:
258````
259tv4.addFormat({
260        'my-format': function () {...},
261        'other-format': function () {...}
262});
263````
264
265## Demos
266
267### Basic usage
268<div class="content inline-demo" markdown="1" data-demo="demo1">
269<pre class="code" id="demo1">
270var schema = {
271        "items": {
272                "type": "boolean"
273        }
274};
275var data1 = [true, false];
276var data2 = [true, 123];
277
278alert("data 1: " + tv4.validate(data1, schema)); // true
279alert("data 2: " + tv4.validate(data2, schema)); // false
280alert("data 2 error: " + JSON.stringify(tv4.error, null, 4));
281</pre>
282</div>
283
284### Use of <code>$ref</code>
285<div class="content inline-demo" markdown="1" data-demo="demo2">
286<pre class="code" id="demo2">
287var schema = {
288        "type": "array",
289        "items": {"$ref": "#"}
290};
291var data1 = [[], [[]]];
292var data2 = [[], [true, []]];
293
294alert("data 1: " + tv4.validate(data1, schema)); // true
295alert("data 2: " + tv4.validate(data2, schema)); // false
296</pre>
297</div>
298
299### Missing schema
300<div class="content inline-demo" markdown="1" data-demo="demo3">
301<pre class="code" id="demo3">
302var schema = {
303        "type": "array",
304        "items": {"$ref": "http://example.com/schema" }
305};
306var data = [1, 2, 3];
307
308alert("Valid: " + tv4.validate(data, schema)); // true
309alert("Missing schemas: " + JSON.stringify(tv4.missing));
310</pre>
311</div>
312
313### Referencing remote schema
314<div class="content inline-demo" markdown="1" data-demo="demo4">
315<pre class="code" id="demo4">
316tv4.addSchema("http://example.com/schema", {
317        "definitions": {
318                "arrayItem": {"type": "boolean"}
319        }
320});
321var schema = {
322        "type": "array",
323        "items": {"$ref": "http://example.com/schema#/definitions/arrayItem" }
324};
325var data1 = [true, false, true];
326var data2 = [1, 2, 3];
327
328alert("data 1: " + tv4.validate(data1, schema)); // true
329alert("data 2: " + tv4.validate(data2, schema)); // false
330</pre>
331</div>
332
333## Supported platforms
334
335* Node.js
336* All modern browsers
337* IE >= 7
338
339## Installation
340
341You can manually download [`tv4.js`](https://raw.github.com/geraintluff/tv4/master/tv4.js) or the minified [`tv4.min.js`](https://raw.github.com/geraintluff/tv4/master/tv4.min.js) and include it in your html to create the global `tv4` variable.
342
343Alternately use it as a CommonJS module:
344
345````js
346var tv4 = require('tv4');
347````
348
349#### npm
350
351````
352$ npm install tv4
353````
354
355#### bower
356
357````
358$ bower install tv4
359````
360
361#### component.io
362
363````
364$ component install geraintluff/tv4
365````
366
367## Build and test
368
369You can rebuild and run the node and browser tests using node.js and [grunt](http://http://gruntjs.com/):
370
371Make sure you have the global grunt cli command:
372````
373$ npm install grunt-cli -g
374````
375
376Clone the git repos, open a shell in the root folder and install the development dependencies:
377
378````
379$ npm install
380````
381
382Rebuild and run the tests:
383````
384$ grunt
385````
386
387It will run a build and display one Spec-style report for the node.js and two Dot-style reports for both the plain and minified browser tests (via phantomJS). You can also use your own browser to manually run the suites by opening [`test/index.html`](http://geraintluff.github.io/tv4/test/index.html) and [`test/index-min.html`](http://geraintluff.github.io/tv4/test/index-min.html).
388
389## Contributing
390
391Pull-requests for fixes and expansions are welcome. Edit the partial files in `/source` and add your tests in a suitable suite or folder under `/test/tests` and run `grunt` to rebuild and run the test suite. Try to maintain an idiomatic coding style and add tests for any new features. It is recommend to discuss big changes in an Issue.
392
393## Packages using tv4
394
395* [chai-json-schema](http://chaijs.com/plugins/chai-json-schema) is a [Chai Assertion Library](http://chaijs.com) plugin to assert values against json-schema.
396* [grunt-tv4](http://www.github.com/Bartvds/grunt-tv4) is a plugin for [Grunt](http://http://gruntjs.com/) that uses tv4 to bulk validate json files.
397
398## License
399
400The code is available as "public domain", meaning that it is completely free to use, without any restrictions at all.  Read the full license [here](http://geraintluff.github.com/tv4/LICENSE.txt).
401
402It's also available under an [MIT license](http://jsonary.com/LICENSE.txt).
Note: See TracBrowser for help on using the repository browser.