diff --git a/.vscode/launch.json b/.vscode/launch.json index f137ad72..5f7b5665 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -63,7 +63,8 @@ "index.test.js", "error.test.js", "override.test.js", - "unit.test.js" + "unit.test.js", + "joi.test.js" ] }] } \ No newline at end of file diff --git a/create.js b/create.js index fc24763b..93606134 100644 --- a/create.js +++ b/create.js @@ -3,7 +3,7 @@ const merge = require('ut-function.merge'); const path = require('path'); const {Broker, ServiceBus} = require('ut-bus'); const through2 = require('through2'); -const joi = require('joi'); +const joi = require('./joi'); function getDataDirectory() { if (process.browser) return '/'; diff --git a/joi/bigint.js b/joi/bigint.js new file mode 100644 index 00000000..3a9edcb2 --- /dev/null +++ b/joi/bigint.js @@ -0,0 +1,11 @@ +const bigintRegex = /^[1-9]{1}[0-9]{0,18}$/; +module.exports = joi => ({ + type: 'bigint', + base: joi.any(), + messages: { + 'bigint.base': '{{#label}} must be a bigint' + }, + validate(value, helpers) { + if (!bigintRegex.test(String(value))) return { value, errors: helpers.error('bigint.base') }; + } +}); diff --git a/joi/index.js b/joi/index.js new file mode 100644 index 00000000..9e9cc2cf --- /dev/null +++ b/joi/index.js @@ -0,0 +1,3 @@ +module.exports = require('joi').extend( + require('./bigint') +); diff --git a/test/joi.test.js b/test/joi.test.js new file mode 100644 index 00000000..7bacc515 --- /dev/null +++ b/test/joi.test.js @@ -0,0 +1,26 @@ +const tap = require('tap'); +const joi = require('../joi'); + +tap.test('bigint', t => { + const test = (name, schema, input, ok = true) => t.test(name, assert => { + assert.comment(`schema: ${JSON.stringify(schema.describe())}`); + assert.comment(`input: ${JSON.stringify(input)}`); + const { error = '' } = schema.validate(input); + if (ok) assert.notOk(error, 'pass'); + else assert.ok(error, error.message || 'error expected'); + assert.end(); + }); + test('number', joi.bigint(), 1); + test('random string', joi.bigint(), 'asd', false); + test('stringified number', joi.bigint(), '11'); + test('stringified number overflow', joi.bigint(), '1'.repeat(20), false); + test('zero', joi.bigint(), 0, false); + test('negative number', joi.bigint(), -1, false); + test('boolean', joi.bigint(), false, false); + test('null', joi.bigint(), null, false); + test('null explicitly allowed', joi.bigint().allow(null), null); + test('object int value', joi.object({test: joi.bigint()}), {test: 1}); + test('object random string value', joi.object({test: joi.bigint()}), {test: 'asd'}, false); + test('array int item', joi.array().items(joi.bigint()), [123]); + t.end(); +});