1 | const Ajv = require('ajv');
|
2 | const logger = require('../../lib/logger').gateway;
|
3 |
|
4 | const ajv = new Ajv({
|
5 | useDefaults: true,
|
6 | coerceTypes: true,
|
7 | verbose: true,
|
8 | logger
|
9 | });
|
10 |
|
11 | require('ajv-keywords')(ajv, 'instanceof');
|
12 |
|
13 | const registeredKeys = [];
|
14 |
|
15 | function register(type, name, schema) {
|
16 | |
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 | if (!schema) {
|
24 | logger.warn(`${name} ${type} hasn't provided a schema. Validation for this ${type} will be skipped.`);
|
25 | return () => ({ isValid: true });
|
26 | } else {
|
27 | if (!schema.$id) {
|
28 | throw new Error('The schema must have the $id property.');
|
29 | }
|
30 |
|
31 | if (registeredKeys.findIndex(keys => keys.$id === schema.$id) === -1) {
|
32 | ajv.addSchema(schema);
|
33 | registeredKeys.push({ type, $id: schema.$id });
|
34 | } else {
|
35 | ajv.removeSchema(schema.$id).addSchema(schema);
|
36 | }
|
37 | }
|
38 |
|
39 | return (data) => validate(schema.$id, data);
|
40 | }
|
41 |
|
42 | function find(param = null) {
|
43 | if (param) {
|
44 | const item = ajv.getSchema(param);
|
45 | if (item) {
|
46 | return { schema: item.schema };
|
47 | }
|
48 | }
|
49 |
|
50 | return registeredKeys
|
51 | .filter(item => !param || item.type === param)
|
52 | .map(key => ({ type: key.type, schema: ajv.getSchema(key.$id).schema }));
|
53 | }
|
54 |
|
55 | const validate = (id, data) =>
|
56 | ({ isValid: ajv.validate(id, data), error: ajv.errorsText() });
|
57 |
|
58 | module.exports = {
|
59 | register,
|
60 | find,
|
61 | validate
|
62 | };
|