Repository: glennjones/hapi-swagger
Pull request #506 (2018-03-13 16:57:03)

RegExp pattern in generated swagger.json should be compatible with the Swagger UI and other tools
Currently, tools like Swagger UI that support pattern="<regex>" validation fail for any endpoint from the hapi-swagger-generated document that includes a pattern. Tools are using new RegExp(strExp) for parsing and don't expect to see the slashes etc (see https://github.com/swagger-api/swagger-ui/blob/master/src/core/utils.js#L465)

From the examples, it looks like OpenAPI defines an element "pattern" as a RegularExpressionBody, not the full form with the RegularExpressionFlags and slashes (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md, https://www.ecma-international.org/ecma-262/5.1/#sec-7.8.5). Tools like Swagger UI expect the pattern to be in the source/RegularExpressionBody form.

There seems to be a related issue #418 that would be fixed by this PR.

Here's the patch and we'd be very thankful if a new version could be released with it.


Patch:
diff --git a/lib/properties.js b/lib/properties.js
index 87446b8..763eae7 100644
--- a/lib/properties.js
+++ b/lib/properties.js
@@ -270,12 +270,12 @@ internals.properties.prototype.parseString = function (property, joiObj) {
     joiObj._tests.forEach((test) => {
         // Joi post v10
         if (Utilities.isObject(test.arg) && test.arg.pattern) {
-            property.pattern = test.arg.pattern.toString();
+            property.pattern = test.arg.pattern.source;
         }
         // Joi pre v10
         /* $lab:coverage:off$ */
         if (Utilities.isRegex(test.arg)) {
-            property.pattern = test.arg.toString();
+            property.pattern = test.arg.source;
         }
         /* $lab:coverage:on$ */
     });


Test patch:
diff --git a/test/unit/property-test.js b/test/unit/property-test.js
index 0480fdd..4c3e5ce 100644
--- a/test/unit/property-test.js
+++ b/test/unit/property-test.js
@@ -120,7 +120,7 @@ lab.experiment('property - ', () => {
         expect(propertiesNoAlt.parseProperty('x', Joi.string().max(10), null, 'body', true, false)).to.equal({ 'type': 'string', 'maxLength': 10 });
         expect(propertiesNoAlt.parseProperty('x', Joi.string().regex(/^[a-zA-Z0-9]{3,30}/), null, 'body', true, false)).to.equal({
             'type': 'string',
-            'pattern': '/^[a-zA-Z0-9]{3,30}/'
+            'pattern': '^[a-zA-Z0-9]{3,30}'
         });
 
         expect(propertiesAlt.parseProperty('x', Joi.string().length(0, 'utf8'), null, 'body', true, false)).to.equal({ 'type': 'string', 'x-constraint': { 'length': 0 } });
@@ -182,7 +182,7 @@ lab.experiment('property - ', () => {
        */
 
         expect(propertiesAlt.parseProperty('x', Joi.string().guid(), null, 'body', true, true)).to.equal({ 'type': 'string', 'x-format': { 'guid': true } });
-        expect(propertiesAlt.parseProperty('x', Joi.string().hex(), null, 'body', true, true)).to.equal({ 'type': 'string', 'pattern': '/^[a-f0-9]+$/i', 'x-format': { 'hex': true } });
+        expect(propertiesAlt.parseProperty('x', Joi.string().hex(), null, 'body', true, true)).to.equal({ 'type': 'string', 'pattern': '^[a-f0-9]+$', 'x-format': { 'hex': true } });
         expect(propertiesAlt.parseProperty('x', Joi.string().guid(), null, 'body', true, true)).to.equal({ 'type': 'string', 'x-format': { 'guid': true } });
         expect(propertiesAlt.parseProperty('x', Joi.string().hostname(), null, 'body', true, true)).to.equal({ 'type': 'string', 'x-format': { 'hostname': true } });
         expect(propertiesAlt.parseProperty('x', Joi.string().isoDate(), null, 'body', true, true)).to.equal({ 'type': 'string', 'x-format': { 'isoDate': true } });