joi-to-json 2.1.1 → 2.2.2
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/README.md +5 -1
- package/index.js +1 -0
- package/lib/convertors/v12.js +7 -1
- package/lib/parsers/json.js +33 -11
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Objective
|
|
4
4
|
|
|
5
|
-
I have been using [joi](https://
|
|
5
|
+
I have been using [joi](https://joi.dev/) a lot in different Node.js projects to guard the API.
|
|
6
6
|
It's **The most powerful schema description language and data validator for JavaScript.** as it said.
|
|
7
7
|
|
|
8
8
|
Many times, we need to utilize this schema description to produce other output, such as Swagger OpenAPI doc.
|
|
@@ -103,6 +103,10 @@ You can optionally set below environment variables:
|
|
|
103
103
|
|
|
104
104
|
* `CASE_PATTERN=joi-obj-12` to control which version of joi obj to test
|
|
105
105
|
|
|
106
|
+
## Known Limitation
|
|
107
|
+
|
|
108
|
+
* For `object.pattern` usage in Joi, `pattern` parameter can only be a regular expression now as I cannot convert Joi object to regex yet.
|
|
109
|
+
|
|
106
110
|
## License
|
|
107
111
|
|
|
108
112
|
MIT
|
package/index.js
CHANGED
|
@@ -51,6 +51,7 @@ function parse(joiObj, type = 'json') {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
const joiBaseSpec = new convertor().toBaseSpec(joiObj.describe())
|
|
54
|
+
// fs.writeFileSync(`./internal_${convertor.getSupportVersion()}_${type}.json`, JSON.stringify(joiBaseSpec, null, 2))
|
|
54
55
|
const parser = parsers[type]
|
|
55
56
|
if (!parser) {
|
|
56
57
|
throw new Error(`No parser is registered for ${type}`)
|
package/lib/convertors/v12.js
CHANGED
|
@@ -37,7 +37,13 @@ class JoiSpecConvertor {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
_convertAlternatives(joiObj) {
|
|
40
|
-
|
|
40
|
+
let isWhenCase = false
|
|
41
|
+
if (joiObj.alternatives.length === 1) {
|
|
42
|
+
const condition = joiObj.alternatives[0]
|
|
43
|
+
isWhenCase = !!condition.then || !!condition.otherwise
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (isWhenCase) {
|
|
41
47
|
// when case
|
|
42
48
|
joiObj.type = 'any'
|
|
43
49
|
joiObj.whens = joiObj.alternatives
|
package/lib/parsers/json.js
CHANGED
|
@@ -28,6 +28,7 @@ class JoiJsonSchemaParser {
|
|
|
28
28
|
this._setAlternativesProperties(schema, joiSpec)
|
|
29
29
|
this._setAnyProperties(schema, joiSpec)
|
|
30
30
|
this._addNullTypeIfNullable(schema, joiSpec)
|
|
31
|
+
this._setMetaProperties(schema, joiSpec)
|
|
31
32
|
|
|
32
33
|
return schema
|
|
33
34
|
}
|
|
@@ -156,9 +157,9 @@ class JoiJsonSchemaParser {
|
|
|
156
157
|
* For dynamic key scenarios to store the pattern as key
|
|
157
158
|
* and have the properties be as with other examples
|
|
158
159
|
*/
|
|
159
|
-
|
|
160
|
+
if (joiSpec.patterns) {
|
|
160
161
|
_.each(joiSpec.patterns, patternObj => {
|
|
161
|
-
if (typeof patternObj.rule !== 'object') {
|
|
162
|
+
if (typeof patternObj.rule !== 'object' || typeof patternObj.regex === 'undefined') {
|
|
162
163
|
return
|
|
163
164
|
}
|
|
164
165
|
|
|
@@ -177,6 +178,14 @@ class JoiJsonSchemaParser {
|
|
|
177
178
|
schema.properties[patternObj.regex].required.push(key)
|
|
178
179
|
}
|
|
179
180
|
})
|
|
181
|
+
|
|
182
|
+
schema.patternProperties = schema.patternProperties || {}
|
|
183
|
+
|
|
184
|
+
let regexString = patternObj.regex
|
|
185
|
+
regexString = regexString.indexOf('/') === 0 ? regexString.substring(1) : regexString
|
|
186
|
+
regexString = regexString.lastIndexOf('/') > -1 ? regexString.substring(0, regexString.length - 1) : regexString
|
|
187
|
+
|
|
188
|
+
schema.patternProperties[regexString] = schema.properties[patternObj.regex]
|
|
180
189
|
})
|
|
181
190
|
}
|
|
182
191
|
|
|
@@ -226,11 +235,6 @@ class JoiJsonSchemaParser {
|
|
|
226
235
|
if (fieldDefn.flags && fieldDefn.flags.encoding) {
|
|
227
236
|
fieldSchema.contentEncoding = fieldDefn.flags.encoding
|
|
228
237
|
}
|
|
229
|
-
_.forEach(fieldDefn.meta, (m) => {
|
|
230
|
-
if (m.contentMediaType) {
|
|
231
|
-
fieldSchema.contentMediaType = m.contentMediaType
|
|
232
|
-
}
|
|
233
|
-
})
|
|
234
238
|
|
|
235
239
|
const ruleArgFieldName = this.ruleArgFieldName
|
|
236
240
|
|
|
@@ -358,10 +362,17 @@ class JoiJsonSchemaParser {
|
|
|
358
362
|
return
|
|
359
363
|
}
|
|
360
364
|
|
|
361
|
-
if (joiSpec.matches.length === 1
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
+
if (joiSpec.matches.length === 1) {
|
|
366
|
+
const match = joiSpec.matches[0]
|
|
367
|
+
if (match.switch) {
|
|
368
|
+
schema.oneOf = _.map(match.switch, (condition) => {
|
|
369
|
+
return this.parse(condition.then || condition.otherwise)
|
|
370
|
+
})
|
|
371
|
+
} else if (match.then || match.otherwise) {
|
|
372
|
+
schema.oneOf = []
|
|
373
|
+
if (match.then) schema.oneOf.push(this.parse(match.then))
|
|
374
|
+
if (match.otherwise) schema.oneOf.push(this.parse(match.otherwise))
|
|
375
|
+
}
|
|
365
376
|
} else {
|
|
366
377
|
schema.oneOf = _.map(joiSpec.matches, (match) => {
|
|
367
378
|
return this.parse(match.schema)
|
|
@@ -398,6 +409,17 @@ class JoiJsonSchemaParser {
|
|
|
398
409
|
'null'
|
|
399
410
|
]
|
|
400
411
|
}
|
|
412
|
+
|
|
413
|
+
_setMetaProperties(schema, joiSpec) {
|
|
414
|
+
_.forEach(joiSpec.metas, (m) => {
|
|
415
|
+
if (m.contentMediaType) {
|
|
416
|
+
schema.contentMediaType = m.contentMediaType
|
|
417
|
+
}
|
|
418
|
+
if (m.format) {
|
|
419
|
+
schema.format = m.format
|
|
420
|
+
}
|
|
421
|
+
})
|
|
422
|
+
}
|
|
401
423
|
}
|
|
402
424
|
|
|
403
425
|
module.exports = JoiJsonSchemaParser
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "joi-to-json",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "joi to JSON / OpenAPI Schema Converter",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"semver-compare": "^1.0.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"ajv": "^8.
|
|
30
|
+
"ajv": "^8.11.0",
|
|
31
31
|
"ajv-draft-04": "^1.0.0",
|
|
32
|
-
"eslint": "^
|
|
33
|
-
"jest": "^27.
|
|
32
|
+
"eslint": "^8.12.0",
|
|
33
|
+
"jest": "^27.5.1",
|
|
34
34
|
"joi-12": "npm:@commercial/joi@^12.1.0",
|
|
35
35
|
"joi-13": "npm:joi@^13.7.0",
|
|
36
36
|
"joi-14": "npm:joi@^14.3.1",
|