json-2-joi 2.3.2 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +203 -203
- package/README.md +359 -358
- package/index.js +14 -14
- package/lib/resolver.js +669 -666
- package/package.json +54 -54
- package/CHANGELOG.md +0 -214
package/README.md
CHANGED
|
@@ -1,358 +1,359 @@
|
|
|
1
|
-
 [](https://badge.fury.io/js/json-2-joi)
|
|
2
|
-
|
|
3
|
-
# json-2-joi
|
|
4
|
-
|
|
5
|
-
Converts a JSON schema to a Joi schema for object validation.
|
|
6
|
-
|
|
7
|
-
## Change based on the forked version (enjoi):
|
|
8
|
-
|
|
9
|
-
- Provided `refineDescription(schema)`, `allowNull`, `forbidArrayNull`, `strictRequired`, `strictEnum`, `enableEnum` options
|
|
10
|
-
- Change cycle reference resovling without self-generating id and rely on $id if defined in JSON schema
|
|
11
|
-
- Support `const` keyword in JSON schema
|
|
12
|
-
- Support `example` setting for Joi based on JSON schema's `examples`, `default` or `enum`
|
|
13
|
-
- Support `contains` keyword in JSON schema using Joi's `has` method
|
|
14
|
-
- Support `$anchor` keyword in JSON schema
|
|
15
|
-
- Support providing `joiOptions` for JOI default instance creation.
|
|
16
|
-
- Support directly passing a Joi instance for schema building.
|
|
17
|
-
- Remove `defaults` API. Please refer to section **Reuse JOI Schema Resolver** for similar usage.
|
|
18
|
-
- Remove `strictMode` and `useDefaults` option.
|
|
19
|
-
- **Big Change** on `$ref` and `subSchemas`. Please refer to [test/test-references.js](test/test-references.js) for detail usage. Currently, four format of `$ref` are supported:
|
|
20
|
-
* id
|
|
21
|
-
* [baseUri]#anchor
|
|
22
|
-
* [baseUri]#/$defs/shared
|
|
23
|
-
* [baseUri]#/$defs/shared/properties/level1
|
|
24
|
-
|
|
25
|
-
**subSchemas will be modified** for two reason:
|
|
26
|
-
* If any subSchema does not have `$id` field, it will be added using the corresponding key in `subSchemas` object.
|
|
27
|
-
* New key-value pair will be added into it if the schema or any its subschema being parsed has `$id` field.
|
|
28
|
-
|
|
29
|
-
## Usage
|
|
30
|
-
|
|
31
|
-
### Schema Support
|
|
32
|
-
|
|
33
|
-
`json-2-joi` does not support all of json-schema.
|
|
34
|
-
|
|
35
|
-
Here is a list of some known missing keyword support still being worked on:
|
|
36
|
-
|
|
37
|
-
- `object:patternProperties` - unsupported due to Joi limitations.
|
|
38
|
-
|
|
39
|
-
Please file issues for other unsupported features.
|
|
40
|
-
|
|
41
|
-
### API
|
|
42
|
-
|
|
43
|
-
- `json2Joi.schema(schema [, options, joiInstance])`
|
|
44
|
-
- `schema` - a JSON schema or a string type representation (such as `'integer'`).
|
|
45
|
-
- `options` - an (optional) object of additional options such as `subSchemas` and custom `types`.
|
|
46
|
-
- `joiInstance` - a (optional) Joi instance to be used. When passed, it will be used directly. `extensions` option does not take effect and the Object/Array auto coerce extensions will not be included as well.
|
|
47
|
-
- `json2Joi.resolver(options [, joiInstance])` - Creates a schema resolver based on `options`. `joiInstance` is same as above.
|
|
48
|
-
|
|
49
|
-
### Options
|
|
50
|
-
|
|
51
|
-
- `subSchemas` - an (optional) object with keys representing schema ids, and values representing schemas.
|
|
52
|
-
- `extensions` - an array of extensions to pass [joi.extend](https://github.com/hapijs/joi/blob/master/API.md#extendextension).
|
|
53
|
-
- `joiOptions` - Options directly passed to Joi for instance creation. If the `noDefaults` is set `true`, `default()` will NOT be called and applied to Joi schema.
|
|
54
|
-
- `refineDescription(schema)` - an (optional) function to call to apply to the JSON schema so that it's possible to return customized description.
|
|
55
|
-
- `refineType(type, format)` - an (optional) function to call to apply to type based on the type and format of the JSON schema.
|
|
56
|
-
- `refineSchema(joiSchema, jsonSchema)` - an (optional) function to call to apply to adjust Joi schema base on the original JSON schema. Primary use case is handling `nullable` flag in OpenAPI 3.0
|
|
57
|
-
- `allowNull` - Default as `false`. When `true` and the field has no `enum` setting, `null` value will be allowed.
|
|
58
|
-
- `
|
|
59
|
-
- `
|
|
60
|
-
- `
|
|
61
|
-
- `
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
*
|
|
99
|
-
* Original `
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
t.ok(
|
|
270
|
-
t.ok(!
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
'
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
1
|
+
 [](https://badge.fury.io/js/json-2-joi)
|
|
2
|
+
|
|
3
|
+
# json-2-joi
|
|
4
|
+
|
|
5
|
+
Converts a JSON schema to a Joi schema for object validation.
|
|
6
|
+
|
|
7
|
+
## Change based on the forked version (enjoi):
|
|
8
|
+
|
|
9
|
+
- Provided `refineDescription(schema)`, `allowNull`, `forbidArrayNull`, `strictRequired`, `strictEnum`, `enableEnum`, `customizedNullValues` options
|
|
10
|
+
- Change cycle reference resovling without self-generating id and rely on $id if defined in JSON schema
|
|
11
|
+
- Support `const` keyword in JSON schema
|
|
12
|
+
- Support `example` setting for Joi based on JSON schema's `examples`, `default` or `enum`
|
|
13
|
+
- Support `contains` keyword in JSON schema using Joi's `has` method
|
|
14
|
+
- Support `$anchor` keyword in JSON schema
|
|
15
|
+
- Support providing `joiOptions` for JOI default instance creation.
|
|
16
|
+
- Support directly passing a Joi instance for schema building.
|
|
17
|
+
- Remove `defaults` API. Please refer to section **Reuse JOI Schema Resolver** for similar usage.
|
|
18
|
+
- Remove `strictMode` and `useDefaults` option.
|
|
19
|
+
- **Big Change** on `$ref` and `subSchemas`. Please refer to [test/test-references.js](test/test-references.js) for detail usage. Currently, four format of `$ref` are supported:
|
|
20
|
+
* id
|
|
21
|
+
* [baseUri]#anchor
|
|
22
|
+
* [baseUri]#/$defs/shared
|
|
23
|
+
* [baseUri]#/$defs/shared/properties/level1
|
|
24
|
+
|
|
25
|
+
**subSchemas will be modified** for two reason:
|
|
26
|
+
* If any subSchema does not have `$id` field, it will be added using the corresponding key in `subSchemas` object.
|
|
27
|
+
* New key-value pair will be added into it if the schema or any its subschema being parsed has `$id` field.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
### Schema Support
|
|
32
|
+
|
|
33
|
+
`json-2-joi` does not support all of json-schema.
|
|
34
|
+
|
|
35
|
+
Here is a list of some known missing keyword support still being worked on:
|
|
36
|
+
|
|
37
|
+
- `object:patternProperties` - unsupported due to Joi limitations.
|
|
38
|
+
|
|
39
|
+
Please file issues for other unsupported features.
|
|
40
|
+
|
|
41
|
+
### API
|
|
42
|
+
|
|
43
|
+
- `json2Joi.schema(schema [, options, joiInstance])`
|
|
44
|
+
- `schema` - a JSON schema or a string type representation (such as `'integer'`).
|
|
45
|
+
- `options` - an (optional) object of additional options such as `subSchemas` and custom `types`.
|
|
46
|
+
- `joiInstance` - a (optional) Joi instance to be used. When passed, it will be used directly. `extensions` option does not take effect and the Object/Array auto coerce extensions will not be included as well.
|
|
47
|
+
- `json2Joi.resolver(options [, joiInstance])` - Creates a schema resolver based on `options`. `joiInstance` is same as above.
|
|
48
|
+
|
|
49
|
+
### Options
|
|
50
|
+
|
|
51
|
+
- `subSchemas` - an (optional) object with keys representing schema ids, and values representing schemas.
|
|
52
|
+
- `extensions` - an array of extensions to pass [joi.extend](https://github.com/hapijs/joi/blob/master/API.md#extendextension).
|
|
53
|
+
- `joiOptions` - Options directly passed to Joi for instance creation. If the `noDefaults` is set `true`, `default()` will NOT be called and applied to Joi schema.
|
|
54
|
+
- `refineDescription(schema)` - an (optional) function to call to apply to the JSON schema so that it's possible to return customized description.
|
|
55
|
+
- `refineType(type, format)` - an (optional) function to call to apply to type based on the type and format of the JSON schema.
|
|
56
|
+
- `refineSchema(joiSchema, jsonSchema)` - an (optional) function to call to apply to adjust Joi schema base on the original JSON schema. Primary use case is handling `nullable` flag in OpenAPI 3.0
|
|
57
|
+
- `allowNull` - Default as `false`. When `true` and the field has no `enum` setting, `null` value will be allowed.
|
|
58
|
+
- `customizedNullValues` - Default as `[null]`. When provided, the value in the array will be treated valid null value when schema is 'null' type or other allowing null case.
|
|
59
|
+
- `forbidArrayNull` - Default as `true`. When `false` and `allowNull` is true, `null` value will be allowed for array type field.
|
|
60
|
+
- `strictRequired` - Default as `false`. When `true`, `null` (and empty string additionally for string type) will NOT be allowed for those `required` field in object.
|
|
61
|
+
- `strictEnum` - Default as `true`. When `false`, and `allowNull` is `true`, `null` (and empty string additionally for string type) will be added to `enum` list.
|
|
62
|
+
- `enableEnum` - Default as `true`. When `false`, `enum` restriction will not be added to Joi Schema.
|
|
63
|
+
|
|
64
|
+
Example:
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
const Joi = require('joi');
|
|
68
|
+
const Json2Joi = require('json-2-joi');
|
|
69
|
+
|
|
70
|
+
const schema = Json2Joi.schema({
|
|
71
|
+
type: 'object',
|
|
72
|
+
properties: {
|
|
73
|
+
firstName: {
|
|
74
|
+
description: 'First name.',
|
|
75
|
+
type: 'string'
|
|
76
|
+
},
|
|
77
|
+
lastName: {
|
|
78
|
+
description: 'Last name.',
|
|
79
|
+
type: 'string'
|
|
80
|
+
},
|
|
81
|
+
age: {
|
|
82
|
+
description: 'Age in years',
|
|
83
|
+
type: 'integer',
|
|
84
|
+
minimum: 1
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
'required': ['firstName', 'lastName']
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const { error, value } = schema.validate({firstName: 'John', lastName: 'Doe', age: 45});
|
|
91
|
+
```
|
|
92
|
+
schema.additionalProperties !== false
|
|
93
|
+
### joiOptions
|
|
94
|
+
|
|
95
|
+
When this option is provided, a Joi instance will be created as `joiInstance = Joi.defaults((schema) => schema.options(joiOptions));` for building Joi Schema.
|
|
96
|
+
|
|
97
|
+
As a result:
|
|
98
|
+
* `unknown` setting (originally set by schema.additionalProperties !== false) of the schema will take effect only if `allowUnknown` is NOT provided in `joiOptions`.
|
|
99
|
+
* Original `useDefaults` option will be replaced by `noDefaults` in `joiOptions`.
|
|
100
|
+
* Original `strictMode` option will be replaced by `convert` in `joiOptions`.
|
|
101
|
+
|
|
102
|
+
### Sub Schemas
|
|
103
|
+
|
|
104
|
+
Sub-schemas can be provided through the `subSchemas` option for `$ref` values to lookup against.
|
|
105
|
+
|
|
106
|
+
Example:
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
const schema = Json2Joi.schema({
|
|
110
|
+
$id: 'top',
|
|
111
|
+
type: 'object',
|
|
112
|
+
properties: {
|
|
113
|
+
product: {
|
|
114
|
+
$ref: 'prod'
|
|
115
|
+
},
|
|
116
|
+
suggestions: {
|
|
117
|
+
type: 'array',
|
|
118
|
+
items: {
|
|
119
|
+
type: 'object',
|
|
120
|
+
properties: {
|
|
121
|
+
product: {
|
|
122
|
+
$ref: 'product'
|
|
123
|
+
},
|
|
124
|
+
weight: {
|
|
125
|
+
$ref: 'measurement'
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}, {
|
|
132
|
+
subSchemas: {
|
|
133
|
+
measurement: {
|
|
134
|
+
type: 'object',
|
|
135
|
+
properties: {
|
|
136
|
+
quantity: {
|
|
137
|
+
$anchor: 'subNumber',
|
|
138
|
+
type: 'number'
|
|
139
|
+
},
|
|
140
|
+
unit: {
|
|
141
|
+
type: 'string'
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
product: {
|
|
146
|
+
$id: 'prod',
|
|
147
|
+
type: 'object',
|
|
148
|
+
properties: {
|
|
149
|
+
isUsed: {
|
|
150
|
+
$anchor: 'subBoolean',
|
|
151
|
+
type: 'boolean'
|
|
152
|
+
},
|
|
153
|
+
isDangerous: {
|
|
154
|
+
$ref: '#subBoolean'
|
|
155
|
+
},
|
|
156
|
+
width: {
|
|
157
|
+
$ref: 'measurement'
|
|
158
|
+
},
|
|
159
|
+
length: {
|
|
160
|
+
$ref: '#/properties/width'
|
|
161
|
+
},
|
|
162
|
+
price: {
|
|
163
|
+
$ref: 'measurement#subNumber'
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Reuse JOI Schema Resolver
|
|
172
|
+
|
|
173
|
+
Sometimes, we might have a base set of `subSchemas` which is used for building a large number of JSON schema and so we do not want to parse these common `subSchemas` again and again. We can first construct a JOI Schema Resolver first and then convert other JSON one by one.
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
|
|
177
|
+
const json2Joi = Json2Joi.resolver({
|
|
178
|
+
subSchemas: {
|
|
179
|
+
measurement: {
|
|
180
|
+
type: 'object',
|
|
181
|
+
properties: {
|
|
182
|
+
quantity: {
|
|
183
|
+
$anchor: 'subNumber',
|
|
184
|
+
type: 'number'
|
|
185
|
+
},
|
|
186
|
+
unit: {
|
|
187
|
+
type: 'string'
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const weightSchema = json2Joi.convert({
|
|
195
|
+
type: 'object',
|
|
196
|
+
properties: {
|
|
197
|
+
weight: {
|
|
198
|
+
$ref: 'measurement'
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const lengthSchema = json2Joi.convert({
|
|
204
|
+
type: 'object',
|
|
205
|
+
properties: {
|
|
206
|
+
length: {
|
|
207
|
+
$ref: 'measurement'
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### Override options during conversion
|
|
214
|
+
|
|
215
|
+
When reusing the Resolver and calling `convert` API, it's possible that different schema might have different requirement.
|
|
216
|
+
|
|
217
|
+
It's possible to override these options for each conversion:
|
|
218
|
+
|
|
219
|
+
* refineType
|
|
220
|
+
* refineSchema
|
|
221
|
+
* refineDescription
|
|
222
|
+
* allowNull
|
|
223
|
+
* forbidArrayNull
|
|
224
|
+
* strictRequired
|
|
225
|
+
* strictEnum
|
|
226
|
+
* enableEnum
|
|
227
|
+
* noDefaults (Copied from `joiOptions` for the construction time)
|
|
228
|
+
|
|
229
|
+
However, the overriden options do not have impact on the `subSchemas` as they are preprocessed during Resolver construction.
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
const subSchemas = {
|
|
233
|
+
measurement: {
|
|
234
|
+
type: 'object',
|
|
235
|
+
properties: {
|
|
236
|
+
quantity: {
|
|
237
|
+
type: 'number',
|
|
238
|
+
enum: [0, 1]
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const enjoi = Enjoi.resolver({
|
|
244
|
+
subSchemas,
|
|
245
|
+
enableEnum: false
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
const jsonSchema = {
|
|
249
|
+
type: 'object',
|
|
250
|
+
properties: {
|
|
251
|
+
weight: {
|
|
252
|
+
type: 'object',
|
|
253
|
+
properties: {
|
|
254
|
+
quantity: {
|
|
255
|
+
type: 'number',
|
|
256
|
+
enum: [0, 1]
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
length: {
|
|
261
|
+
$ref: 'measurement'
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const schema1 = enjoi.convert(jsonSchema, { enableEnum: true });
|
|
267
|
+
const schema2 = enjoi.convert(jsonSchema);
|
|
268
|
+
|
|
269
|
+
t.ok(schema1.validate({ weight: { quantity: 2 } }).error, 'follow overridden options');
|
|
270
|
+
t.ok(!schema1.validate({ length: { quantity: 2 } }).error, 'no impact on subschemas');
|
|
271
|
+
t.ok(!schema2.validate({ weight: { quantity: 2 } }).error, 'still use original options');
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Custom Types
|
|
275
|
+
|
|
276
|
+
Custom types can be provided through the `extensions` option.
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
const schema = Json2Joi.schema({
|
|
280
|
+
type: 'thing'
|
|
281
|
+
}, {
|
|
282
|
+
extensions: [{
|
|
283
|
+
type: 'thing',
|
|
284
|
+
base: Joi.any()
|
|
285
|
+
}]
|
|
286
|
+
});
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Also with functions.
|
|
290
|
+
|
|
291
|
+
```javascript
|
|
292
|
+
const schema = Json2Joi.schema({
|
|
293
|
+
type: 'thing'
|
|
294
|
+
}, {
|
|
295
|
+
extensions: [{
|
|
296
|
+
type: 'thing',
|
|
297
|
+
validate(value, helpers) {
|
|
298
|
+
if (value !== 'foobar') {
|
|
299
|
+
return { value, errors: helpers.error('thing.foobar') };
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
messages: {
|
|
303
|
+
'thing.foobar': '{#label} must be \'foobar\''
|
|
304
|
+
}
|
|
305
|
+
}]
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Refine Type
|
|
310
|
+
|
|
311
|
+
You can use the refine type function to help refine types based on `type` and `format`. This will allow transforming a type for lookup.
|
|
312
|
+
|
|
313
|
+
```javascript
|
|
314
|
+
const schema = Json2Joi.schema({
|
|
315
|
+
type: 'string',
|
|
316
|
+
format: 'email'
|
|
317
|
+
}, {
|
|
318
|
+
extensions: [{
|
|
319
|
+
type: 'email',
|
|
320
|
+
base: Joi.string().email()
|
|
321
|
+
}],
|
|
322
|
+
refineType(type, format) {
|
|
323
|
+
if (type === 'string' && format === 'email') {
|
|
324
|
+
return 'email';
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
This can be used in conjunction with function based `extensions` for additional logic:
|
|
331
|
+
|
|
332
|
+
```javascript
|
|
333
|
+
const schemaDesc = {
|
|
334
|
+
type: 'string',
|
|
335
|
+
format: 'email',
|
|
336
|
+
'x-test': true
|
|
337
|
+
}
|
|
338
|
+
const schema = Json2Joi.schema(schemaDesc, {
|
|
339
|
+
extensions: [{
|
|
340
|
+
type: 'email',
|
|
341
|
+
validate(value, helpers) {
|
|
342
|
+
const validator = schemaDesc['x-test'] ? Joi.string().email().equal('test@example.com') : Joi.string().email();
|
|
343
|
+
const validation = validator.validate(value);
|
|
344
|
+
if (validation.error) {
|
|
345
|
+
return { value, errors: validation.error };
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}],
|
|
349
|
+
refineType(type, format) {
|
|
350
|
+
if (type === 'string' && format === 'email') {
|
|
351
|
+
return 'email';
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### Extensions
|
|
358
|
+
|
|
359
|
+
Refer to Joi documentation on extensions: https://hapi.dev/module/joi/api/?v=17#extensions
|