From 9c6c89435d9b0403aeaf968e25944778da84240b Mon Sep 17 00:00:00 2001 From: Nicolas Morel Date: Sat, 11 Mar 2023 15:24:25 +0100 Subject: [PATCH] chore: upgrade modules --- .npmrc | 1 + API.md | 2 + benchmarks/.npmrc | 1 + benchmarks/bench.js | 6 +- benchmarks/package.json | 8 +-- browser/.npmrc | 1 + browser/package.json | 29 ++++---- browser/tests/index.js | 25 ++++++- browser/webpack.config.js | 28 +++++++- lib/annotate.js | 4 +- lib/base.js | 145 +++++++++++++++++++------------------- lib/cache.js | 7 +- lib/common.js | 3 +- lib/compile.js | 46 ++++++------ lib/extend.js | 21 +++--- lib/index.d.ts | 13 +++- lib/index.js | 19 +++-- lib/manifest.js | 31 ++++---- lib/messages.js | 21 +++--- lib/modify.js | 20 +++--- lib/ref.js | 32 ++++----- lib/state.js | 9 ++- lib/template.js | 14 ++-- lib/trace.js | 8 +-- lib/types/alternatives.js | 19 +++-- lib/types/any.js | 10 +-- lib/types/array.js | 18 +++-- lib/types/binary.js | 4 +- lib/types/boolean.js | 6 +- lib/types/date.js | 6 +- lib/types/function.js | 8 +-- lib/types/keys.js | 30 ++++---- lib/types/link.js | 20 +++--- lib/types/number.js | 8 +-- lib/types/string.js | 90 +++++++++++------------ lib/types/symbol.js | 10 +-- lib/validator.js | 33 ++++----- lib/values.js | 9 ++- package.json | 19 ++--- test/trace.js | 2 +- test/types/string.js | 33 ++++++++- 41 files changed, 444 insertions(+), 375 deletions(-) create mode 100644 .npmrc create mode 100644 benchmarks/.npmrc create mode 100644 browser/.npmrc diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..43c97e719 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/API.md b/API.md index 58fca5168..8890db585 100755 --- a/API.md +++ b/API.md @@ -2727,6 +2727,7 @@ Requires the string value to be a valid domain name. - `options` - optional settings: - `allowFullyQualified` - if `true`, domains ending with a `.` character are permitted. Defaults to `false`. - `allowUnicode` - if `true`, Unicode characters are permitted. Defaults to `true`. + - `allowUnderscore` - if `true`, underscores (`_`) are allowed in the domain name. Defaults to `false`. - `minDomainSegments` - number of segments required for the domain. Defaults to `2`. - `maxDomainSegments` - maximum number of allowed domain segments. Default to no limit. - `tlds` - options for TLD (top level domain) validation. By default, the TLD must be a valid @@ -2754,6 +2755,7 @@ Requires the string value to be a valid email address. - `options` - optional settings: - `allowFullyQualified` - if `true`, domains ending with a `.` character are permitted. Defaults to `false`. - `allowUnicode` - if `true`, Unicode characters are permitted. Defaults to `true`. + - `allowUnderscore` - if `true`, underscores (`_`) are allowed in the domain name. Defaults to `false`. - `ignoreLength` - if `true`, ignore invalid email length errors. Defaults to `false`. - `minDomainSegments` - number of segments required for the domain. The default setting excludes single segment domains such as `example@io` which is a valid email but very uncommon. Defaults diff --git a/benchmarks/.npmrc b/benchmarks/.npmrc new file mode 100644 index 000000000..cafe685a1 --- /dev/null +++ b/benchmarks/.npmrc @@ -0,0 +1 @@ +package-lock=true diff --git a/benchmarks/bench.js b/benchmarks/bench.js index bf46c449f..4be6873c3 100755 --- a/benchmarks/bench.js +++ b/benchmarks/bench.js @@ -2,7 +2,7 @@ const Fs = require('fs'); -const Assert = require('@hapi/hoek/lib/assert'); +const { assert } = require('@hapi/hoek'); const Benchmark = require('benchmark'); const Bossy = require('@hapi/bossy'); const Chalk = require('chalk'); @@ -74,8 +74,8 @@ const test = ([name, initFn, testFn]) => { const [schema, valid, invalid] = versionPick(initFn)(); - Assert(valid === undefined || !testFn(schema, valid).error, 'validation must not fail for: ' + name); - Assert(invalid === undefined || testFn(schema, invalid).error, 'validation must fail for: ' + name); + assert(valid === undefined || !testFn(schema, valid).error, 'validation must not fail for: ' + name); + assert(invalid === undefined || testFn(schema, invalid).error, 'validation must fail for: ' + name); testFn = versionPick(testFn); Suite.add(name + (valid !== undefined ? ' (valid)' : ''), () => { diff --git a/benchmarks/package.json b/benchmarks/package.json index 62b506095..7d195472e 100644 --- a/benchmarks/package.json +++ b/benchmarks/package.json @@ -7,13 +7,13 @@ "full-bench": "npm run bench-update -- --joi @hapi/joi && npm test" }, "dependencies": { - "@hapi/bossy": "^4.0.3", - "@hapi/hoek": "^6.2.4", + "@hapi/bossy": "^6.0.1", + "@hapi/hoek": "^11.0.2", "@hapi/joi": "^15.1.0", "benchmark": "^2.1.4", "chalk": "^2.4.1", - "cli-table": "^0.3.1", + "cli-table": "^0.3.11", "d3-format": "^1.3.2", - "joi": "^17.6.4" + "joi": "^17.8.1" } } diff --git a/browser/.npmrc b/browser/.npmrc new file mode 100644 index 000000000..43c97e719 --- /dev/null +++ b/browser/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/browser/package.json b/browser/package.json index 0af7b4616..6b48c8b84 100755 --- a/browser/package.json +++ b/browser/package.json @@ -2,26 +2,27 @@ "scripts": { "build": "webpack --mode production", "build-dev": "webpack --mode development", - "build-analyze": "webpack --mode production --profile --json > stats.json", + "build-analyze": "webpack --mode production --stats-optimization-bailout --profile --json > stats.json", "postbuild-analyze": "webpack-bundle-analyzer stats.json", "test": "karma start" }, "devDependencies": { - "@babel/core": "^7.4.5", - "@babel/plugin-proposal-class-properties": "^7.7.4", - "@babel/preset-env": "^7.4.5", + "@babel/core": "^7.21.0", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/preset-env": "^7.20.2", + "@mixer/webpack-bundle-compare": "^0.1.1", "assert": "^2.0.0", - "babel-loader": "^8.0.6", - "karma": "^4.2.0", - "karma-chrome-launcher": "^3.0.0", - "karma-mocha": "^1.3.0", - "karma-sourcemap-loader": "^0.3.7", + "babel-loader": "^9.1.2", + "karma": "^6.4.1", + "karma-chrome-launcher": "^3.1.1", + "karma-mocha": "^2.0.1", + "karma-sourcemap-loader": "^0.4.0", "karma-webpack": "^5.0.0", - "mocha": "^6.2.0", - "mocha-loader": "^2.0.1", - "util": "^0.12.4", - "webpack": "^5.40.0", + "mocha": "^8.4.0", + "mocha-loader": "^5.1.5", + "util": "^0.12.5", + "webpack": "^5.76.1", "webpack-bundle-analyzer": "^3.4.1", - "webpack-cli": "^4.7.2" + "webpack-cli": "^5.0.1" } } diff --git a/browser/tests/index.js b/browser/tests/index.js index 6d9aaf725..d59403719 100755 --- a/browser/tests/index.js +++ b/browser/tests/index.js @@ -7,7 +7,12 @@ describe('Joi', () => { it('should be able to create schemas', () => { - Joi.string().min(5); + Joi.boolean().truthy('true'); + Joi.number().min(5).max(10).multiple(2); + Joi.array().items(Joi.number().required()); + Joi.object({ + key: Joi.string().required() + }); }); it('should be able to validate data', () => { @@ -29,5 +34,23 @@ describe('Joi', () => { Assert.ok(!schema.validate('test@example.com').error); Assert.ok(schema.validate('test@example.com ').error); Assert.ok(!schema.validate('伊昭傑@郵件.商務').error); + + const schema2 = Joi.string().email({ tlds: { allow: false } }).required(); + Assert.ok(!schema2.validate('test@example.com').error); + Assert.ok(schema2.validate('test@example.com ').error); + Assert.ok(!schema2.validate('伊昭傑@郵件.商務').error); + }); + + it('validates domain', () => { + + const schema = Joi.string().domain().required(); + Assert.ok(!schema.validate('example.com').error); + Assert.ok(schema.validate('example.com ').error); + Assert.ok(!schema.validate('example.商務').error); + + const schema2 = Joi.string().domain({ tlds: { allow: false } }).required(); + Assert.ok(!schema2.validate('example.com').error); + Assert.ok(schema2.validate('example.com ').error); + Assert.ok(!schema2.validate('example.商務').error); }); }); diff --git a/browser/webpack.config.js b/browser/webpack.config.js index 266b24c73..b78ae4e57 100755 --- a/browser/webpack.config.js +++ b/browser/webpack.config.js @@ -3,6 +3,7 @@ const Path = require('path'); const Webpack = require('webpack'); +const { BundleComparisonPlugin } = require('@mixer/webpack-bundle-compare'); module.exports = { @@ -16,6 +17,11 @@ module.exports = { plugins: [ new Webpack.DefinePlugin({ Buffer: false + }), + new BundleComparisonPlugin({ + file: '../stats.msp.gz', + format: 'msgpack', + gzip: true, }) ], module: { @@ -40,10 +46,16 @@ module.exports = { ] ], plugins: [ - '@babel/plugin-proposal-class-properties' + '@babel/plugin-proposal-class-properties', + '@babel/plugin-proposal-optional-chaining', + '@babel/plugin-proposal-nullish-coalescing-operator', ] } } + }, + { + test: /@(hapi|sideway)\//, + sideEffects: false } ] }, @@ -54,7 +66,19 @@ module.exports = { [Path.join(__dirname, '../lib/manifest.js')]: false, [Path.join(__dirname, '../lib/trace.js')]: false, [Path.join(__dirname, '../lib/types/binary.js')]: false, - [Path.join(__dirname, '../node_modules/@sideway/address/lib/tlds.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/tlds/esm/index.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/address/esm/decode.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/hoek/lib/bench.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/hoek/lib/block.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/hoek/lib/contain.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/hoek/lib/flatten.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/hoek/lib/intersect.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/hoek/lib/isPromise.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/hoek/lib/escapeHeaderAttribute.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/hoek/lib/escapeJson.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/hoek/lib/once.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/hoek/lib/reachTemplate.js')]: false, + [Path.join(__dirname, '../node_modules/@hapi/hoek/lib/wait.js')]: false, }, fallback: { url: false, diff --git a/lib/annotate.js b/lib/annotate.js index 42798fc3e..44c4d97dc 100755 --- a/lib/annotate.js +++ b/lib/annotate.js @@ -1,6 +1,6 @@ 'use strict'; -const Clone = require('@hapi/hoek/lib/clone'); +const { clone } = require('@hapi/hoek'); const Common = require('./common'); @@ -22,7 +22,7 @@ exports.error = function (stripColorCodes) { const redBgEscape = stripColorCodes ? '' : '\u001b[41m'; const endColor = stripColorCodes ? '' : '\u001b[0m'; - const obj = Clone(this._original); + const obj = clone(this._original); for (let i = this.details.length - 1; i >= 0; --i) { // Reverse order to process deepest child first const pos = i + 1; diff --git a/lib/base.js b/lib/base.js index 9bd2fd73b..8f8e2cc8a 100755 --- a/lib/base.js +++ b/lib/base.js @@ -1,9 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const Clone = require('@hapi/hoek/lib/clone'); -const DeepEqual = require('@hapi/hoek/lib/deepEqual'); -const Merge = require('@hapi/hoek/lib/merge'); +const { assert, clone, deepEqual, merge } = require('@hapi/hoek'); const Cache = require('./cache'); const Common = require('./common'); @@ -61,7 +58,7 @@ internals.Base = class { describe() { - Assert(typeof Manifest.describe === 'function', 'Manifest functionality disabled'); + assert(typeof Manifest.describe === 'function', 'Manifest functionality disabled'); return Manifest.describe(this); } @@ -75,14 +72,14 @@ internals.Base = class { alter(targets) { - Assert(targets && typeof targets === 'object' && !Array.isArray(targets), 'Invalid targets argument'); - Assert(!this._inRuleset(), 'Cannot set alterations inside a ruleset'); + assert(targets && typeof targets === 'object' && !Array.isArray(targets), 'Invalid targets argument'); + assert(!this._inRuleset(), 'Cannot set alterations inside a ruleset'); const obj = this.clone(); obj.$_terms.alterations = obj.$_terms.alterations || []; for (const target in targets) { const adjuster = targets[target]; - Assert(typeof adjuster === 'function', 'Alteration adjuster for', target, 'must be a function'); + assert(typeof adjuster === 'function', 'Alteration adjuster for', target, 'must be a function'); obj.$_terms.alterations.push({ target, adjuster }); } @@ -92,16 +89,16 @@ internals.Base = class { artifact(id) { - Assert(id !== undefined, 'Artifact cannot be undefined'); - Assert(!this._cache, 'Cannot set an artifact with a rule cache'); + assert(id !== undefined, 'Artifact cannot be undefined'); + assert(!this._cache, 'Cannot set an artifact with a rule cache'); return this.$_setFlag('artifact', id); } cast(to) { - Assert(to === false || typeof to === 'string', 'Invalid to value'); - Assert(to === false || this._definition.cast[to], 'Type', this.type, 'does not support casting to', to); + assert(to === false || typeof to === 'string', 'Invalid to value'); + assert(to === false || this._definition.cast[to], 'Type', this.type, 'does not support casting to', to); return this.$_setFlag('cast', to === false ? undefined : to); } @@ -113,7 +110,7 @@ internals.Base = class { description(desc) { - Assert(desc && typeof desc === 'string', 'Description must be a non-empty string'); + assert(desc && typeof desc === 'string', 'Description must be a non-empty string'); return this.$_setFlag('description', desc); } @@ -131,15 +128,15 @@ internals.Base = class { error(err) { - Assert(err, 'Missing error'); - Assert(err instanceof Error || typeof err === 'function', 'Must provide a valid Error object or a function'); + assert(err, 'Missing error'); + assert(err instanceof Error || typeof err === 'function', 'Must provide a valid Error object or a function'); return this.$_setFlag('error', err); } example(example, options = {}) { - Assert(example !== undefined, 'Missing example'); + assert(example !== undefined, 'Missing example'); Common.assertOptions(options, ['override']); return this._inner('examples', example, { single: true, override: options.override }); @@ -148,13 +145,13 @@ internals.Base = class { external(method, description) { if (typeof method === 'object') { - Assert(!description, 'Cannot combine options with description'); + assert(!description, 'Cannot combine options with description'); description = method.description; method = method.method; } - Assert(typeof method === 'function', 'Method must be a function'); - Assert(description === undefined || description && typeof description === 'string', 'Description must be a non-empty string'); + assert(typeof method === 'function', 'Method must be a function'); + assert(description === undefined || description && typeof description === 'string', 'Description must be a non-empty string'); return this._inner('externals', { method, description }, { single: true }); } @@ -175,8 +172,8 @@ internals.Base = class { return this.$_setFlag('id', undefined); } - Assert(typeof id === 'string', 'id must be a non-empty string'); - Assert(/^[^\.]+$/.test(id), 'id cannot contain period character'); + assert(typeof id === 'string', 'id must be a non-empty string'); + assert(/^[^\.]+$/.test(id), 'id cannot contain period character'); return this.$_setFlag('id', id); } @@ -188,23 +185,23 @@ internals.Base = class { label(name) { - Assert(name && typeof name === 'string', 'Label name must be a non-empty string'); + assert(name && typeof name === 'string', 'Label name must be a non-empty string'); return this.$_setFlag('label', name); } meta(meta) { - Assert(meta !== undefined, 'Meta cannot be undefined'); + assert(meta !== undefined, 'Meta cannot be undefined'); return this._inner('metas', meta, { single: true }); } note(...notes) { - Assert(notes.length, 'Missing notes'); + assert(notes.length, 'Missing notes'); for (const note of notes) { - Assert(note && typeof note === 'string', 'Notes must be non-empty strings'); + assert(note && typeof note === 'string', 'Notes must be non-empty strings'); } return this._inner('notes', notes); @@ -212,7 +209,7 @@ internals.Base = class { only(mode = true) { - Assert(typeof mode === 'boolean', 'Invalid mode:', mode); + assert(typeof mode === 'boolean', 'Invalid mode:', mode); return this.$_setFlag('only', mode); } @@ -224,11 +221,11 @@ internals.Base = class { prefs(prefs) { - Assert(prefs, 'Missing preferences'); - Assert(prefs.context === undefined, 'Cannot override context'); - Assert(prefs.externals === undefined, 'Cannot override externals'); - Assert(prefs.warnings === undefined, 'Cannot override warnings'); - Assert(prefs.debug === undefined, 'Cannot override debug'); + assert(prefs, 'Missing preferences'); + assert(prefs.context === undefined, 'Cannot override context'); + assert(prefs.externals === undefined, 'Cannot override externals'); + assert(prefs.warnings === undefined, 'Cannot override warnings'); + assert(prefs.debug === undefined, 'Cannot override debug'); Common.checkPreferences(prefs); @@ -239,7 +236,7 @@ internals.Base = class { presence(mode) { - Assert(['optional', 'required', 'forbidden'].includes(mode), 'Unknown presence mode', mode); + assert(['optional', 'required', 'forbidden'].includes(mode), 'Unknown presence mode', mode); return this.$_setFlag('presence', mode); } @@ -251,7 +248,7 @@ internals.Base = class { result(mode) { - Assert(['raw', 'strip'].includes(mode), 'Unknown result mode', mode); + assert(['raw', 'strip'].includes(mode), 'Unknown result mode', mode); return this.$_setFlag('result', mode); } @@ -277,9 +274,9 @@ internals.Base = class { tag(...tags) { - Assert(tags.length, 'Missing tags'); + assert(tags.length, 'Missing tags'); for (const tag of tags) { - Assert(tag && typeof tag === 'string', 'Tags must be non-empty strings'); + assert(tag && typeof tag === 'string', 'Tags must be non-empty strings'); } return this._inner('tags', tags); @@ -287,7 +284,7 @@ internals.Base = class { unit(name) { - Assert(name && typeof name === 'string', 'Unit name must be a non-empty string'); + assert(name && typeof name === 'string', 'Unit name must be a non-empty string'); return this.$_setFlag('unit', name); } @@ -313,8 +310,8 @@ internals.Base = class { if (!['any', 'link'].includes(obj.type)) { const conditions = when.is ? [when] : when.switch; for (const item of conditions) { - Assert(!item.then || item.then.type === 'any' || item.then.type === obj.type, 'Cannot combine', obj.type, 'with', item.then && item.then.type); - Assert(!item.otherwise || item.otherwise.type === 'any' || item.otherwise.type === obj.type, 'Cannot combine', obj.type, 'with', item.otherwise && item.otherwise.type); + assert(!item.then || item.then.type === 'any' || item.then.type === obj.type, 'Cannot combine', obj.type, 'with', item.then && item.then.type); + assert(!item.otherwise || item.otherwise.type === 'any' || item.otherwise.type === obj.type, 'Cannot combine', obj.type, 'with', item.otherwise && item.otherwise.type); } } @@ -327,9 +324,9 @@ internals.Base = class { cache(cache) { - Assert(!this._inRuleset(), 'Cannot set caching inside a ruleset'); - Assert(!this._cache, 'Cannot override schema cache'); - Assert(this._flags.artifact === undefined, 'Cannot cache a rule with an artifact'); + assert(!this._inRuleset(), 'Cannot set caching inside a ruleset'); + assert(!this._cache, 'Cannot override schema cache'); + assert(this._flags.artifact === undefined, 'Cannot cache a rule with an artifact'); const obj = this.clone(); obj._cache = cache || Cache.provider.provision(); @@ -345,10 +342,10 @@ internals.Base = class { concat(source) { - Assert(Common.isSchema(source), 'Invalid schema object'); - Assert(this.type === 'any' || source.type === 'any' || source.type === this.type, 'Cannot merge type', this.type, 'with another type:', source.type); - Assert(!this._inRuleset(), 'Cannot concatenate onto a schema with open ruleset'); - Assert(!source._inRuleset(), 'Cannot concatenate a schema with open ruleset'); + assert(Common.isSchema(source), 'Invalid schema object'); + assert(this.type === 'any' || source.type === 'any' || source.type === this.type, 'Cannot merge type', this.type, 'with another type:', source.type); + assert(!this._inRuleset(), 'Cannot concatenate onto a schema with open ruleset'); + assert(!source._inRuleset(), 'Cannot concatenate a schema with open ruleset'); let obj = this.clone(); @@ -401,16 +398,16 @@ internals.Base = class { obj._flags.empty = obj._flags.empty.concat(source._flags.empty); const flags = Object.assign({}, source._flags); delete flags.empty; - Merge(obj._flags, flags); + merge(obj._flags, flags); } else if (source._flags.empty) { obj._flags.empty = source._flags.empty; const flags = Object.assign({}, source._flags); delete flags.empty; - Merge(obj._flags, flags); + merge(obj._flags, flags); } else { - Merge(obj._flags, source._flags); + merge(obj._flags, source._flags); } // Terms @@ -446,7 +443,7 @@ internals.Base = class { extend(options) { - Assert(!options.base, 'Cannot extend type with another base'); + assert(!options.base, 'Cannot extend type with another base'); return Extend.type(this, options); } @@ -459,7 +456,7 @@ internals.Base = class { fork(paths, adjuster) { - Assert(!this._inRuleset(), 'Cannot fork inside a ruleset'); + assert(!this._inRuleset(), 'Cannot fork inside a ruleset'); let obj = this; // eslint-disable-line consistent-this for (let path of [].concat(paths)) { @@ -476,19 +473,19 @@ internals.Base = class { const def = this._definition; Common.assertOptions(options, Object.keys(def.modifiers)); - Assert(this.$_temp.ruleset !== false, 'Cannot apply rules to empty ruleset or the last rule added does not support rule properties'); + assert(this.$_temp.ruleset !== false, 'Cannot apply rules to empty ruleset or the last rule added does not support rule properties'); const start = this.$_temp.ruleset === null ? this._rules.length - 1 : this.$_temp.ruleset; - Assert(start >= 0 && start < this._rules.length, 'Cannot apply rules to empty ruleset'); + assert(start >= 0 && start < this._rules.length, 'Cannot apply rules to empty ruleset'); const obj = this.clone(); for (let i = start; i < obj._rules.length; ++i) { const original = obj._rules[i]; - const rule = Clone(original); + const rule = clone(original); for (const name in options) { def.modifiers[name](rule, options[name]); - Assert(rule.name === original.name, 'Cannot change rule name'); + assert(rule.name === original.name, 'Cannot change rule name'); } obj._rules[i] = rule; @@ -504,7 +501,7 @@ internals.Base = class { get ruleset() { - Assert(!this._inRuleset(), 'Cannot start a new ruleset without closing the previous one'); + assert(!this._inRuleset(), 'Cannot start a new ruleset without closing the previous one'); const obj = this.clone(); obj.$_temp.ruleset = obj._rules.length; @@ -520,7 +517,7 @@ internals.Base = class { targets = [].concat(targets); - Assert(!this._inRuleset(), 'Cannot tailor inside a ruleset'); + assert(!this._inRuleset(), 'Cannot tailor inside a ruleset'); let obj = this; // eslint-disable-line consistent-this @@ -528,7 +525,7 @@ internals.Base = class { for (const { target, adjuster } of this.$_terms.alterations) { if (targets.includes(target)) { obj = adjuster(obj); - Assert(Common.isSchema(obj), 'Alteration adjuster for', target, 'failed to return a schema object'); + assert(Common.isSchema(obj), 'Alteration adjuster for', target, 'failed to return a schema object'); } } } @@ -563,11 +560,11 @@ internals.Base = class { options = { name: options }; } - Assert(options && typeof options === 'object', 'Invalid options'); - Assert(options.name && typeof options.name === 'string', 'Invalid rule name'); + assert(options && typeof options === 'object', 'Invalid options'); + assert(options.name && typeof options.name === 'string', 'Invalid rule name'); for (const key in options) { - Assert(key[0] !== '_', 'Cannot set private rule properties'); + assert(key[0] !== '_', 'Cannot set private rule properties'); } const rule = Object.assign({}, options); // Shallow cloned @@ -577,14 +574,14 @@ internals.Base = class { const definition = this._definition.rules[rule.method]; const args = rule.args; - Assert(definition, 'Unknown rule', rule.method); + assert(definition, 'Unknown rule', rule.method); // Args const obj = this.clone(); if (args) { - Assert(Object.keys(args).length === 1 || Object.keys(args).length === this._definition.rules[rule.name].args.length, 'Invalid rule definition for', this.type, rule.name); + assert(Object.keys(args).length === 1 || Object.keys(args).length === this._definition.rules[rule.name].args.length, 'Invalid rule definition for', this.type, rule.name); for (const key in args) { let arg = args[key]; @@ -606,7 +603,7 @@ internals.Base = class { if (resolver.assert) { const error = Common.validateArg(arg, key, resolver); - Assert(!error, error, 'or reference'); + assert(!error, error, 'or reference'); } } } @@ -690,7 +687,7 @@ internals.Base = class { $_mutateRebuild() { - Assert(!this._inRuleset(), 'Cannot add this rule inside a ruleset'); + assert(!this._inRuleset(), 'Cannot add this rule inside a ruleset'); this._refs.reset(); this._ids.reset(); @@ -736,14 +733,14 @@ internals.Base = class { $_setFlag(name, value, options = {}) { - Assert(name[0] === '_' || !this._inRuleset(), 'Cannot set flag inside a ruleset'); + assert(name[0] === '_' || !this._inRuleset(), 'Cannot set flag inside a ruleset'); const flag = this._definition.flags[name] || {}; - if (DeepEqual(value, flag.default)) { + if (deepEqual(value, flag.default)) { value = undefined; } - if (DeepEqual(value, this._flags[name])) { + if (deepEqual(value, this._flags[name])) { return this; } @@ -790,7 +787,7 @@ internals.Base = class { target._valids = this._valids && this._valids.clone(); target._invalids = this._invalids && this._invalids.clone(); target._rules = this._rules.slice(); - target._singleRules = Clone(this._singleRules, { shallow: true }); + target._singleRules = clone(this._singleRules, { shallow: true }); target._refs = this._refs.clone(); target._flags = Object.assign({}, this._flags); target._cache = null; @@ -828,8 +825,8 @@ internals.Base = class { Common.assertOptions(options, 'literal'); - Assert(value !== undefined, 'Missing', flag, 'value'); - Assert(typeof value === 'function' || !options.literal, 'Only function value supports literal option'); + assert(value !== undefined, 'Missing', flag, 'value'); + assert(typeof value === 'function' || !options.literal, 'Only function value supports literal option'); if (typeof value === 'function' && options.literal) { @@ -938,7 +935,7 @@ internals.Base = class { _inner(type, values, options = {}) { - Assert(!this._inRuleset(), `Cannot set ${type} inside a ruleset`); + assert(!this._inRuleset(), `Cannot set ${type} inside a ruleset`); const obj = this.clone(); if (!obj.$_terms[type] || @@ -1025,14 +1022,14 @@ internals.Base = class { } for (const value of values) { - Assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined'); - Assert(value !== Common.symbols.override, 'Override must be the first value'); + assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined'); + assert(value !== Common.symbols.override, 'Override must be the first value'); const other = key === '_invalids' ? '_valids' : '_invalids'; if (obj[other]) { obj[other].remove(value); if (!obj[other].length) { - Assert(key === '_valids' || !obj._flags.only, 'Setting invalid value', value, 'leaves schema rejecting all values due to previous valid rule'); + assert(key === '_valids' || !obj._flags.only, 'Setting invalid value', value, 'leaves schema rejecting all values due to previous valid rule'); obj[other] = null; } } diff --git a/lib/cache.js b/lib/cache.js index 32c61e0e4..6ce913a53 100755 --- a/lib/cache.js +++ b/lib/cache.js @@ -1,7 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const Clone = require('@hapi/hoek/lib/clone'); +const { assert, clone } = require('@hapi/hoek'); const Common = require('./common'); @@ -28,7 +27,7 @@ internals.Cache = class { constructor(options = {}) { Common.assertOptions(options, ['max']); - Assert(options.max === undefined || options.max && options.max > 0 && isFinite(options.max), 'Invalid max cache size'); + assert(options.max === undefined || options.max && options.max > 0 && isFinite(options.max), 'Invalid max cache size'); this._max = options.max || internals.max; @@ -66,7 +65,7 @@ internals.Cache = class { const node = this._map.get(key); if (node) { this._list.first(node); - return Clone(node.value); + return clone(node.value); } } diff --git a/lib/common.js b/lib/common.js index 7d572c139..ff4f89ffe 100755 --- a/lib/common.js +++ b/lib/common.js @@ -1,7 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const AssertError = require('@hapi/hoek/lib/error'); +const { assert: Assert, AssertError } = require('@hapi/hoek'); const Pkg = require('../package.json'); diff --git a/lib/compile.js b/lib/compile.js index 5593b7c90..6a648298d 100755 --- a/lib/compile.js +++ b/lib/compile.js @@ -1,6 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); +const { assert } = require('@hapi/hoek'); const Common = require('./common'); const Ref = require('./ref'); @@ -30,10 +30,10 @@ exports.schema = function (Joi, config, options = {}) { internals.schema = function (Joi, config, options) { - Assert(config !== undefined, 'Invalid undefined schema'); + assert(config !== undefined, 'Invalid undefined schema'); if (Array.isArray(config)) { - Assert(config.length, 'Invalid empty array schema'); + assert(config.length, 'Invalid empty array schema'); if (config.length === 1) { config = config[0]; @@ -57,7 +57,7 @@ internals.schema = function (Joi, config, options) { return Joi.custom(config); } - Assert(typeof config === 'object', 'Invalid schema content:', typeof config); + assert(typeof config === 'object', 'Invalid schema content:', typeof config); if (Common.isResolvable(config)) { return valid(Joi, config); @@ -85,7 +85,7 @@ internals.schema = function (Joi, config, options) { return valid(Joi.date(), config); } - Assert(Object.getPrototypeOf(config) === Object.getPrototypeOf({}), 'Schema can only contain plain objects'); + assert(Object.getPrototypeOf(config) === Object.getPrototypeOf({}), 'Schema can only contain plain objects'); return Joi.object().keys(config); }; @@ -105,7 +105,7 @@ exports.compile = function (root, schema, options = {}) { const any = schema && schema[Common.symbols.any]; if (any) { - Assert(options.legacy || any.version === Common.version, 'Cannot mix different versions of joi schemas:', any.version, Common.version); + assert(options.legacy || any.version === Common.version, 'Cannot mix different versions of joi schemas:', any.version, Common.version); return schema; } @@ -150,7 +150,7 @@ internals.walk = function (schema) { return { root: schema[any.root], compile: any.compile }; } - Assert(Object.getPrototypeOf(schema) === Object.getPrototypeOf({}), 'Schema can only contain plain objects'); + assert(Object.getPrototypeOf(schema) === Object.getPrototypeOf({}), 'Schema can only contain plain objects'); for (const key in schema) { const compiler = internals.walk(schema[key]); @@ -172,7 +172,7 @@ internals.simple = function (value) { exports.when = function (schema, condition, options) { if (options === undefined) { - Assert(condition && typeof condition === 'object', 'Missing options'); + assert(condition && typeof condition === 'object', 'Missing options'); options = condition; condition = Ref.create('.'); @@ -187,17 +187,17 @@ exports.when = function (schema, condition, options) { // Schema condition if (Common.isSchema(condition)) { - Assert(options.is === undefined, '"is" can not be used with a schema condition'); - Assert(options.not === undefined, '"not" can not be used with a schema condition'); - Assert(options.switch === undefined, '"switch" can not be used with a schema condition'); + assert(options.is === undefined, '"is" can not be used with a schema condition'); + assert(options.not === undefined, '"not" can not be used with a schema condition'); + assert(options.switch === undefined, '"switch" can not be used with a schema condition'); return internals.condition(schema, { is: condition, then: options.then, otherwise: options.otherwise, break: options.break }); } // Single condition - Assert(Ref.isRef(condition) || typeof condition === 'string', 'Invalid condition:', condition); - Assert(options.not === undefined || options.is === undefined, 'Cannot combine "is" with "not"'); + assert(Ref.isRef(condition) || typeof condition === 'string', 'Invalid condition:', condition); + assert(options.not === undefined || options.is === undefined, 'Cannot combine "is" with "not"'); if (options.switch === undefined) { let rule = options; @@ -206,8 +206,8 @@ exports.when = function (schema, condition, options) { } let is = rule.is !== undefined ? schema.$_compile(rule.is) : schema.$_root.invalid(null, false, 0, '').required(); - Assert(rule.then !== undefined || rule.otherwise !== undefined, 'options must have at least one of "then", "otherwise", or "switch"'); - Assert(rule.break === undefined || rule.then === undefined || rule.otherwise === undefined, 'Cannot specify then, otherwise, and break all together'); + assert(rule.then !== undefined || rule.otherwise !== undefined, 'options must have at least one of "then", "otherwise", or "switch"'); + assert(rule.break === undefined || rule.then === undefined || rule.otherwise === undefined, 'Cannot specify then, otherwise, and break all together'); if (options.is !== undefined && !Ref.isRef(options.is) && @@ -221,10 +221,10 @@ exports.when = function (schema, condition, options) { // Switch statement - Assert(Array.isArray(options.switch), '"switch" must be an array'); - Assert(options.is === undefined, 'Cannot combine "switch" with "is"'); - Assert(options.not === undefined, 'Cannot combine "switch" with "not"'); - Assert(options.then === undefined, 'Cannot combine "switch" with "then"'); + assert(Array.isArray(options.switch), '"switch" must be an array'); + assert(options.is === undefined, 'Cannot combine "switch" with "is"'); + assert(options.not === undefined, 'Cannot combine "switch" with "not"'); + assert(options.then === undefined, 'Cannot combine "switch" with "then"'); const rule = { ref: exports.ref(condition), @@ -238,8 +238,8 @@ exports.when = function (schema, condition, options) { Common.assertOptions(test, last ? ['is', 'then', 'otherwise'] : ['is', 'then']); - Assert(test.is !== undefined, 'Switch statement missing "is"'); - Assert(test.then !== undefined, 'Switch statement missing "then"'); + assert(test.is !== undefined, 'Switch statement missing "is"'); + assert(test.then !== undefined, 'Switch statement missing "then"'); const item = { is: schema.$_compile(test.is), @@ -253,10 +253,10 @@ exports.when = function (schema, condition, options) { } if (last) { - Assert(options.otherwise === undefined || test.otherwise === undefined, 'Cannot specify "otherwise" inside and outside a "switch"'); + assert(options.otherwise === undefined || test.otherwise === undefined, 'Cannot specify "otherwise" inside and outside a "switch"'); const otherwise = options.otherwise !== undefined ? options.otherwise : test.otherwise; if (otherwise !== undefined) { - Assert(rule.break === undefined, 'Cannot specify both otherwise and break'); + assert(rule.break === undefined, 'Cannot specify both otherwise and break'); item.otherwise = schema.$_compile(otherwise); } } diff --git a/lib/extend.js b/lib/extend.js index 2a5acf7b4..9b7fa2eb2 100755 --- a/lib/extend.js +++ b/lib/extend.js @@ -1,7 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const Clone = require('@hapi/hoek/lib/clone'); +const { assert, clone } = require('@hapi/hoek'); const Common = require('./common'); const Messages = require('./messages'); @@ -13,7 +12,7 @@ const internals = {}; exports.type = function (from, options) { const base = Object.getPrototypeOf(from); - const prototype = Clone(base); + const prototype = clone(base); const schema = from._assign(Object.create(prototype)); const def = Object.assign({}, options); // Shallow cloned delete def.base; @@ -38,7 +37,7 @@ exports.type = function (from, options) { if (def.terms) { for (const name in def.terms) { // Only apply own terms const term = def.terms[name]; - Assert(schema.$_terms[name] === undefined, 'Invalid term override for', def.type, name); + assert(schema.$_terms[name] === undefined, 'Invalid term override for', def.type, name); schema.$_terms[name] = term.init; terms[name] = term; } @@ -82,7 +81,7 @@ exports.type = function (from, options) { if (def.rules) { for (const name in def.rules) { const rule = def.rules[name]; - Assert(typeof rule === 'object', 'Invalid rule definition for', def.type, name); + assert(typeof rule === 'object', 'Invalid rule definition for', def.type, name); let method = rule.method; if (method === undefined) { @@ -93,11 +92,11 @@ exports.type = function (from, options) { } if (method) { - Assert(!prototype[name], 'Rule conflict in', def.type, name); + assert(!prototype[name], 'Rule conflict in', def.type, name); prototype[name] = method; } - Assert(!rules[name], 'Rule conflict in', def.type, name); + assert(!rules[name], 'Rule conflict in', def.type, name); rules[name] = rule; if (rule.alias) { @@ -115,7 +114,7 @@ exports.type = function (from, options) { arg = { name: arg }; } - Assert(!rule.argsByName.has(arg.name), 'Duplicated argument name', arg.name); + assert(!rule.argsByName.has(arg.name), 'Duplicated argument name', arg.name); if (Common.isSchema(arg.assert)) { arg.assert = arg.assert.strict().label(arg.name); @@ -135,10 +134,10 @@ exports.type = function (from, options) { const modifiers = Object.assign({}, parent.modifiers); if (def.modifiers) { for (const name in def.modifiers) { - Assert(!prototype[name], 'Rule conflict in', def.type, name); + assert(!prototype[name], 'Rule conflict in', def.type, name); const modifier = def.modifiers[name]; - Assert(typeof modifier === 'function', 'Invalid modifier definition for', def.type, name); + assert(typeof modifier === 'function', 'Invalid modifier definition for', def.type, name); const method = function (arg) { @@ -158,7 +157,7 @@ exports.type = function (from, options) { prototype._super = base; schema.$_super = {}; // Backwards compatibility for (const override in def.overrides) { - Assert(base[override], 'Cannot override missing', override); + assert(base[override], 'Cannot override missing', override); def.overrides[override][Common.symbols.parent] = base[override]; schema.$_super[override] = base[override].bind(schema); // Backwards compatibility } diff --git a/lib/index.d.ts b/lib/index.d.ts index 8d0f415b4..2d99da396 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -290,6 +290,12 @@ declare namespace Joi { * @default true */ allowUnicode?: boolean; + /** + * If `true`, underscores (`_`) are allowed in the domain name + * + * @default false + */ + allowUnderscore?: boolean; /** * if `true`, ignore invalid email length errors. * @@ -341,7 +347,12 @@ declare namespace Joi { * @default true */ allowUnicode?: boolean; - + /** + * If `true`, underscores (`_`) are allowed in the domain name + * + * @default false + */ + allowUnderscore?: boolean; /** * Options for TLD (top level domain) validation. By default, the TLD must be a valid name listed on the [IANA registry](http://data.iana.org/TLD/tlds-alpha-by-domain.txt) * diff --git a/lib/index.js b/lib/index.js index 784aef4b1..2565deffa 100755 --- a/lib/index.js +++ b/lib/index.js @@ -1,7 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const Clone = require('@hapi/hoek/lib/clone'); +const { assert, clone } = require('@hapi/hoek'); const Cache = require('./cache'); const Common = require('./common'); @@ -54,7 +53,7 @@ internals.root = function () { for (const type of root._types) { root[type] = function (...args) { - Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments'); + assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments'); return internals.generate(this, internals.types[type], args); }; } @@ -109,7 +108,7 @@ internals.methods = { build(desc) { - Assert(typeof Manifest.build === 'function', 'Manifest functionality disabled'); + assert(typeof Manifest.build === 'function', 'Manifest functionality disabled'); return Manifest.build(this, desc); }, @@ -125,12 +124,12 @@ internals.methods = { defaults(modifier) { - Assert(typeof modifier === 'function', 'modifier must be a function'); + assert(typeof modifier === 'function', 'modifier must be a function'); const joi = Object.assign({}, this); for (const type of joi._types) { const schema = modifier(joi[type]()); - Assert(Common.isSchema(schema), 'modifier must return a valid schema object'); + assert(Common.isSchema(schema), 'modifier must return a valid schema object'); joi[type] = function (...args) { @@ -152,7 +151,7 @@ internals.methods = { Schemas = Schemas || require('./schemas'); - Assert(extensions.length, 'You need to provide at least one extension'); + assert(extensions.length, 'You need to provide at least one extension'); this.assert(extensions, Schemas.extensions); const joi = Object.assign({}, this); @@ -167,7 +166,7 @@ internals.methods = { const expanded = internals.expandExtension(extension, joi); for (const item of expanded) { - Assert(joi[item.type] === undefined || joi._types.has(item.type), 'Cannot override name', item.type); + assert(joi[item.type] === undefined || joi._types.has(item.type), 'Cannot override name', item.type); const base = item.base || this.any(); const schema = Extend.type(base, item); @@ -236,7 +235,7 @@ internals.assert = function (value, schema, annotate, args /* [message], [option const display = annotate && typeof error.annotate === 'function' ? error.annotate() : error.message; if (error instanceof Errors.ValidationError === false) { - error = Clone(error); + error = clone(error); } error.message = message ? `${message} ${display}` : display; @@ -246,7 +245,7 @@ internals.assert = function (value, schema, annotate, args /* [message], [option internals.generate = function (root, schema, args) { - Assert(root, 'Must be invoked on a Joi instance.'); + assert(root, 'Must be invoked on a Joi instance.'); schema.$_root = root; diff --git a/lib/manifest.js b/lib/manifest.js index 8fed3c923..715f2547b 100755 --- a/lib/manifest.js +++ b/lib/manifest.js @@ -1,7 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const Clone = require('@hapi/hoek/lib/clone'); +const { assert, clone } = require('@hapi/hoek'); const Common = require('./common'); const Messages = require('./messages'); @@ -41,7 +40,7 @@ exports.describe = function (schema) { // Preferences if (schema._preferences) { - desc.preferences = Clone(schema._preferences, { shallow: ['messages'] }); + desc.preferences = clone(schema._preferences, { shallow: ['messages'] }); delete desc.preferences[Common.symbols.prefs]; if (desc.preferences.messages) { desc.preferences.messages = Messages.decompile(desc.preferences.messages); @@ -106,7 +105,7 @@ exports.describe = function (schema) { continue; } - Assert(!desc[term], 'Cannot describe schema due to internal name conflict with', term); + assert(!desc[term], 'Cannot describe schema due to internal name conflict with', term); const items = schema.$_terms[term]; if (!items) { @@ -126,7 +125,7 @@ exports.describe = function (schema) { continue; } - Assert(def.terms[term], 'Term', term, 'missing configuration'); + assert(def.terms[term], 'Term', term, 'missing configuration'); const manifest = def.terms[term].manifest; const mapped = typeof manifest === 'object'; if (!items.length && @@ -155,7 +154,7 @@ exports.describe = function (schema) { // Single if (manifest === 'single') { - Assert(normalized.length === 1, 'Term', term, 'contains more than one item'); + assert(normalized.length === 1, 'Term', term, 'contains more than one item'); desc[term] = normalized[0]; continue; } @@ -187,7 +186,7 @@ internals.describe = function (item, options = {}) { } if (options.assign === 'options') { - return Clone(item); + return clone(item); } if (Buffer && Buffer.isBuffer(item)) { // $lab:coverage:ignore$ @@ -264,7 +263,7 @@ internals.Builder = class { if (desc.flags) { for (const flag in desc.flags) { const setter = def.flags[flag] && def.flags[flag].setter || flag; - Assert(typeof schema[setter] === 'function', 'Invalid flag', flag, 'for type', desc.type); + assert(typeof schema[setter] === 'function', 'Invalid flag', flag, 'for type', desc.type); schema = schema[setter](this.build(desc.flags[flag])); } } @@ -289,7 +288,7 @@ internals.Builder = class { if (desc.rules) { for (const rule of desc.rules) { - Assert(typeof schema[rule.name] === 'function', 'Invalid rule', rule.name, 'for type', desc.type); + assert(typeof schema[rule.name] === 'function', 'Invalid rule', rule.name, 'for type', desc.type); const args = []; if (rule.args) { @@ -301,13 +300,13 @@ internals.Builder = class { const keys = Object.keys(built); const definition = def.rules[rule.name].args; if (definition) { - Assert(keys.length <= definition.length, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to', definition.length, ', found', keys.length, ')'); + assert(keys.length <= definition.length, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to', definition.length, ', found', keys.length, ')'); for (const { name } of definition) { args.push(built[name]); } } else { - Assert(keys.length === 1, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to 1, found', keys.length, ')'); + assert(keys.length === 1, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to 1, found', keys.length, ')'); args.push(built[keys[0]]); } } @@ -339,7 +338,7 @@ internals.Builder = class { continue; } - Assert(def.terms[key], 'Term', key, 'missing configuration'); + assert(def.terms[key], 'Term', key, 'missing configuration'); const manifest = def.terms[key].manifest; if (manifest === 'schema') { @@ -394,7 +393,7 @@ internals.Builder = class { } if (options.assign === 'options') { - return Clone(desc); + return clone(desc); } if (options.assign === 'regex') { @@ -411,7 +410,7 @@ internals.Builder = class { if (Object.keys(desc).length === 1) { if (desc.buffer) { - Assert(Buffer, 'Buffers are not supported'); + assert(Buffer, 'Buffers are not supported'); return Buffer && Buffer.from(desc.buffer, 'binary'); // $lab:coverage:ignore$ } @@ -432,12 +431,12 @@ internals.Builder = class { } if (desc.special) { - Assert(['deep'].includes(desc.special), 'Unknown special value', desc.special); + assert(['deep'].includes(desc.special), 'Unknown special value', desc.special); return Common.symbols.deepDefault; } if (desc.value) { - return Clone(desc.value); + return clone(desc.value); } } diff --git a/lib/messages.js b/lib/messages.js index 5eef308cd..d5318b368 100755 --- a/lib/messages.js +++ b/lib/messages.js @@ -1,7 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const Clone = require('@hapi/hoek/lib/clone'); +const { assert, clone } = require('@hapi/hoek'); const Template = require('./template'); @@ -14,22 +13,22 @@ exports.compile = function (messages, target) { // Single value string ('plain error message', 'template {error} message') if (typeof messages === 'string') { - Assert(!target, 'Cannot set single message string'); + assert(!target, 'Cannot set single message string'); return new Template(messages); } // Single value template if (Template.isTemplate(messages)) { - Assert(!target, 'Cannot set single message template'); + assert(!target, 'Cannot set single message template'); return messages; } // By error code { 'number.min': } - Assert(typeof messages === 'object' && !Array.isArray(messages), 'Invalid message options'); + assert(typeof messages === 'object' && !Array.isArray(messages), 'Invalid message options'); - target = target ? Clone(target) : {}; + target = target ? clone(target) : {}; for (let code in messages) { const message = messages[code]; @@ -48,7 +47,7 @@ exports.compile = function (messages, target) { // By language { english: { 'number.min': } } - Assert(typeof message === 'object' && !Array.isArray(message), 'Invalid message for', code); + assert(typeof message === 'object' && !Array.isArray(message), 'Invalid message for', code); const language = code; target[language] = target[language] || {}; @@ -63,7 +62,7 @@ exports.compile = function (messages, target) { continue; } - Assert(typeof localized === 'string', 'Invalid message for', code, 'in', language); + assert(typeof localized === 'string', 'Invalid message for', code, 'in', language); target[language][code] = new Template(localized); } } @@ -135,7 +134,7 @@ exports.merge = function (base, extended) { // By error code { 'number.min': } - const target = Clone(base); + const target = clone(base); for (let code in extended) { const message = extended[code]; @@ -154,7 +153,7 @@ exports.merge = function (base, extended) { // By language { english: { 'number.min': } } - Assert(typeof message === 'object' && !Array.isArray(message), 'Invalid message for', code); + assert(typeof message === 'object' && !Array.isArray(message), 'Invalid message for', code); const language = code; target[language] = target[language] || {}; @@ -169,7 +168,7 @@ exports.merge = function (base, extended) { continue; } - Assert(typeof localized === 'string', 'Invalid message for', code, 'in', language); + assert(typeof localized === 'string', 'Invalid message for', code, 'in', language); target[language][code] = new Template(localized); } } diff --git a/lib/modify.js b/lib/modify.js index 6f1484847..70d1f13cb 100755 --- a/lib/modify.js +++ b/lib/modify.js @@ -1,6 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); +const { assert } = require('@hapi/hoek'); const Common = require('./common'); const Ref = require('./ref'); @@ -35,12 +35,12 @@ exports.Ids = internals.Ids = class { } for (const [id, value] of source._byId.entries()) { - Assert(!this._byKey.has(id), 'Schema id conflicts with existing key:', id); + assert(!this._byKey.has(id), 'Schema id conflicts with existing key:', id); this._byId.set(id, value); } for (const [key, value] of source._byKey.entries()) { - Assert(!this._byId.has(key), 'Schema key conflicts with existing id:', key); + assert(!this._byId.has(key), 'Schema key conflicts with existing id:', key); this._byKey.set(key, value); } } @@ -52,7 +52,7 @@ exports.Ids = internals.Ids = class { const tail = chain.shift(); let adjusted = { id: tail.id, schema: adjuster(tail.schema) }; - Assert(Common.isSchema(adjusted.schema), 'adjuster function failed to return a joi schema type'); + assert(Common.isSchema(adjusted.schema), 'adjuster function failed to return a joi schema type'); for (const node of chain) { adjusted = { id: node.id, schema: internals.fork(node.schema, adjusted.id, adjusted.schema) }; @@ -82,7 +82,7 @@ exports.Ids = internals.Ids = class { const current = path[0]; const node = this._get(current); - Assert(node, 'Schema does not contain path', [...behind, ...path].join('.')); + assert(node, 'Schema does not contain path', [...behind, ...path].join('.')); const forward = path.slice(1); if (!forward.length) { @@ -109,15 +109,15 @@ exports.Ids = internals.Ids = class { const id = schema._flags.id; if (id) { const existing = this._byId.get(id); - Assert(!existing || existing.schema === schema, 'Cannot add different schemas with the same id:', id); - Assert(!this._byKey.has(id), 'Schema id conflicts with existing key:', id); + assert(!existing || existing.schema === schema, 'Cannot add different schemas with the same id:', id); + assert(!this._byKey.has(id), 'Schema id conflicts with existing key:', id); this._byId.set(id, { schema, id }); } if (key) { - Assert(!this._byKey.has(key), 'Schema already contains key:', key); - Assert(!this._byId.has(key), 'Schema key conflicts with existing id:', key); + assert(!this._byKey.has(key), 'Schema already contains key:', key); + assert(!this._byId.has(key), 'Schema key conflicts with existing id:', key); this._byKey.set(key, { schema, id: key }); } @@ -134,7 +134,7 @@ exports.Ids = internals.Ids = class { const current = path[0]; const node = this._get(current); - Assert(node, 'Schema does not contain path', [...behind, ...path].join('.')); + assert(node, 'Schema does not contain path', [...behind, ...path].join('.')); nodes = [node, ...nodes]; diff --git a/lib/ref.js b/lib/ref.js index 9f84a7b6d..b834e8713 100755 --- a/lib/ref.js +++ b/lib/ref.js @@ -1,8 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const Clone = require('@hapi/hoek/lib/clone'); -const Reach = require('@hapi/hoek/lib/reach'); +const { assert, clone, reach } = require('@hapi/hoek'); const Common = require('./common'); @@ -24,9 +22,9 @@ const internals = { exports.create = function (key, options = {}) { - Assert(typeof key === 'string', 'Invalid reference key:', key); + assert(typeof key === 'string', 'Invalid reference key:', key); Common.assertOptions(options, ['adjust', 'ancestor', 'in', 'iterables', 'map', 'prefix', 'render', 'separator']); - Assert(!options.prefix || typeof options.prefix === 'object', 'options.prefix must be of type object'); + assert(!options.prefix || typeof options.prefix === 'object', 'options.prefix must be of type object'); const ref = Object.assign({}, internals.defaults, options); delete ref.prefix; @@ -38,7 +36,7 @@ exports.create = function (key, options = {}) { if (ref.type === 'value') { if (context.root) { - Assert(!separator || key[0] !== separator, 'Cannot specify relative path with root prefix'); + assert(!separator || key[0] !== separator, 'Cannot specify relative path with root prefix'); ref.ancestor = 'root'; if (!key) { key = null; @@ -53,7 +51,7 @@ exports.create = function (key, options = {}) { } else { if (ref.ancestor !== undefined) { - Assert(!separator || !key || key[0] !== separator, 'Cannot combine prefix with ancestor option'); + assert(!separator || !key || key[0] !== separator, 'Cannot combine prefix with ancestor option'); } else { const [ancestor, slice] = internals.ancestor(key, separator); @@ -91,20 +89,20 @@ internals.Ref = class { constructor(options) { - Assert(typeof options === 'object', 'Invalid reference construction'); + assert(typeof options === 'object', 'Invalid reference construction'); Common.assertOptions(options, [ 'adjust', 'ancestor', 'in', 'iterables', 'map', 'path', 'render', 'separator', 'type', // Copied 'depth', 'key', 'root', 'display' // Overridden ]); - Assert([false, undefined].includes(options.separator) || typeof options.separator === 'string' && options.separator.length === 1, 'Invalid separator'); - Assert(!options.adjust || typeof options.adjust === 'function', 'options.adjust must be a function'); - Assert(!options.map || Array.isArray(options.map), 'options.map must be an array'); - Assert(!options.map || !options.adjust, 'Cannot set both map and adjust options'); + assert([false, undefined].includes(options.separator) || typeof options.separator === 'string' && options.separator.length === 1, 'Invalid separator'); + assert(!options.adjust || typeof options.adjust === 'function', 'options.adjust must be a function'); + assert(!options.map || Array.isArray(options.map), 'options.map must be an array'); + assert(!options.map || !options.adjust, 'Cannot set both map and adjust options'); Object.assign(this, internals.defaults, options); - Assert(this.type === 'value' || this.ancestor === undefined, 'Non-value references cannot reference ancestors'); + assert(this.type === 'value' || this.ancestor === undefined, 'Non-value references cannot reference ancestors'); if (Array.isArray(this.map)) { this.map = new Map(this.map); @@ -119,7 +117,7 @@ internals.Ref = class { resolve(value, state, prefs, local, options = {}) { - Assert(!this.in || options.in, 'Invalid in() reference usage'); + assert(!this.in || options.in, 'Invalid in() reference usage'); if (this.type === 'global') { return this._resolve(prefs.context, state, options); @@ -137,7 +135,7 @@ internals.Ref = class { return this._resolve(state.ancestors[state.ancestors.length - 1], state, options); } - Assert(this.ancestor <= state.ancestors.length, 'Invalid reference exceeds the schema root:', this.display); + assert(this.ancestor <= state.ancestors.length, 'Invalid reference exceeds the schema root:', this.display); return this._resolve(state.ancestors[this.ancestor - 1], state, options); } @@ -153,7 +151,7 @@ internals.Ref = class { } if (resolved === undefined) { - resolved = Reach(target, this.path, { iterables: this.iterables, functions: true }); + resolved = reach(target, this.path, { iterables: this.iterables, functions: true }); } if (this.adjust) { @@ -398,7 +396,7 @@ exports.Manager = class { clone() { const copy = new exports.Manager(); - copy.refs = Clone(this.refs); + copy.refs = clone(this.refs); return copy; } diff --git a/lib/state.js b/lib/state.js index 8db251b76..03b53580f 100755 --- a/lib/state.js +++ b/lib/state.js @@ -1,7 +1,6 @@ 'use strict'; -const Clone = require('@hapi/hoek/lib/clone'); -const Reach = require('@hapi/hoek/lib/reach'); +const { clone, reach } = require('@hapi/hoek'); const Common = require('./common'); @@ -53,7 +52,7 @@ module.exports = internals.State = class { snapshot() { if (this.mainstay.shadow) { - this._snapshot = Clone(this.mainstay.shadow.node(this.path)); + this._snapshot = clone(this.mainstay.shadow.node(this.path)); } } @@ -127,7 +126,7 @@ internals.Shadow = class { return; } - return Reach(this._values, path, { iterables: true }); + return reach(this._values, path, { iterables: true }); } override(path, node) { @@ -138,7 +137,7 @@ internals.Shadow = class { const parents = path.slice(0, -1); const own = path[path.length - 1]; - const parent = Reach(this._values, parents, { iterables: true }); + const parent = reach(this._values, parents, { iterables: true }); if (node) { parent.set(own, node); diff --git a/lib/template.js b/lib/template.js index 3858ad17f..abc0dcc02 100755 --- a/lib/template.js +++ b/lib/template.js @@ -1,9 +1,7 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const Clone = require('@hapi/hoek/lib/clone'); -const EscapeHtml = require('@hapi/hoek/lib/escapeHtml'); -const Formula = require('@sideway/formula'); +const { assert, clone, escapeHtml } = require('@hapi/hoek'); +const Formula = require('@hapi/formula'); const Common = require('./common'); const Errors = require('./errors'); @@ -30,14 +28,14 @@ module.exports = exports = internals.Template = class { constructor(source, options) { - Assert(typeof source === 'string', 'Template source must be a string'); - Assert(!source.includes('\u0000') && !source.includes('\u0001'), 'Template source cannot contain reserved control characters'); + assert(typeof source === 'string', 'Template source must be a string'); + assert(!source.includes('\u0000') && !source.includes('\u0001'), 'Template source cannot contain reserved control characters'); this.source = source; this.rendered = source; this._template = null; - this._settings = Clone(options); + this._settings = clone(options); this._parse(); } @@ -191,7 +189,7 @@ module.exports = exports = internals.Template = class { const rendered = this._part(part, /* context -> [*/ value, state, prefs, local, options /*] */); const string = internals.stringify(rendered, value, state, prefs, local, options); if (string !== undefined) { - const result = part.raw || (options.errors && options.errors.escapeHtml) === false ? string : EscapeHtml(string); + const result = part.raw || (options.errors && options.errors.escapeHtml) === false ? string : escapeHtml(string); parts.push(internals.wrap(result, part.wrapped && prefs.errors.wrap.label)); } } diff --git a/lib/trace.js b/lib/trace.js index ded4d7e76..90cfa5441 100755 --- a/lib/trace.js +++ b/lib/trace.js @@ -1,7 +1,7 @@ 'use strict'; -const DeepEqual = require('@hapi/hoek/lib/deepEqual'); -const Pinpoint = require('@sideway/pinpoint'); +const { deepEqual } = require('@hapi/hoek'); +const Pinpoint = require('@hapi/pinpoint'); const Errors = require('./errors'); @@ -232,7 +232,7 @@ internals.Store = class { value(state, by, from, to, name) { if (!state.mainstay.debug || - DeepEqual(from, to)) { + deepEqual(from, to)) { return; } @@ -327,7 +327,7 @@ internals.sub = function (paths, skipped) { for (const path of paths) { for (const skip of skipped) { - if (DeepEqual(path.slice(0, skip.length), skip)) { + if (deepEqual(path.slice(0, skip.length), skip)) { return true; } } diff --git a/lib/types/alternatives.js b/lib/types/alternatives.js index e4024959c..25a7f6e7d 100755 --- a/lib/types/alternatives.js +++ b/lib/types/alternatives.js @@ -1,7 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const Merge = require('@hapi/hoek/lib/merge'); +const { assert, merge } = require('@hapi/hoek'); const Any = require('./any'); const Common = require('../common'); @@ -96,7 +95,7 @@ module.exports = Any.extend({ }); }; - return isAnyObj(schema) ? { value: matched.reduce((acc, v) => Merge(acc, v, { mergeArrays: false })) } : { value: matched[matched.length - 1] }; + return isAnyObj(schema) ? { value: matched.reduce((acc, v) => merge(acc, v, { mergeArrays: false })) } : { value: matched[matched.length - 1] }; } // Match any @@ -150,9 +149,9 @@ module.exports = Any.extend({ conditional: { method(condition, options) { - Assert(!this._flags._endedSwitch, 'Unreachable condition'); - Assert(!this._flags.match, 'Cannot combine match mode', this._flags.match, 'with conditional rule'); - Assert(options.break === undefined, 'Cannot use break option with alternatives conditional'); + assert(!this._flags._endedSwitch, 'Unreachable condition'); + assert(!this._flags.match, 'Cannot combine match mode', this._flags.match, 'with conditional rule'); + assert(options.break === undefined, 'Cannot use break option with alternatives conditional'); const obj = this.clone(); @@ -175,11 +174,11 @@ module.exports = Any.extend({ match: { method(mode) { - Assert(['any', 'one', 'all'].includes(mode), 'Invalid alternatives match mode', mode); + assert(['any', 'one', 'all'].includes(mode), 'Invalid alternatives match mode', mode); if (mode !== 'any') { for (const match of this.$_terms.matches) { - Assert(match.schema, 'Cannot combine match mode', mode, 'with conditional rules'); + assert(match.schema, 'Cannot combine match mode', mode, 'with conditional rules'); } } @@ -190,10 +189,10 @@ module.exports = Any.extend({ try: { method(...schemas) { - Assert(schemas.length, 'Missing alternative schemas'); + assert(schemas.length, 'Missing alternative schemas'); Common.verifyFlat(schemas, 'try'); - Assert(!this._flags._endedSwitch, 'Unreachable condition'); + assert(!this._flags._endedSwitch, 'Unreachable condition'); const obj = this.clone(); for (const schema of schemas) { diff --git a/lib/types/any.js b/lib/types/any.js index 2b1ad58b8..94db8c29a 100755 --- a/lib/types/any.js +++ b/lib/types/any.js @@ -1,6 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); +const { assert } = require('@hapi/hoek'); const Base = require('../base'); const Common = require('../common'); @@ -36,8 +36,8 @@ module.exports = Base.extend({ custom: { method(method, description) { - Assert(typeof method === 'function', 'Method must be a function'); - Assert(description === undefined || description && typeof description === 'string', 'Description must be a non-empty string'); + assert(typeof method === 'function', 'Method must be a function'); + assert(description === undefined || description && typeof description === 'string', 'Description must be a non-empty string'); return this.$_addRule({ name: 'custom', args: { method, description } }); }, @@ -64,7 +64,7 @@ module.exports = Base.extend({ shared: { method(schema) { - Assert(Common.isSchema(schema) && schema._flags.id, 'Schema must be a schema with an id'); + assert(Common.isSchema(schema) && schema._flags.id, 'Schema must be a schema with an id'); const obj = this.clone(); obj.$_terms.shared = obj.$_terms.shared || []; @@ -77,7 +77,7 @@ module.exports = Base.extend({ warning: { method(code, local) { - Assert(code && typeof code === 'string', 'Invalid warning code'); + assert(code && typeof code === 'string', 'Invalid warning code'); return this.$_addRule({ name: 'warning', args: { code, local }, warn: true }); }, diff --git a/lib/types/array.js b/lib/types/array.js index 7682e8293..84228cca8 100755 --- a/lib/types/array.js +++ b/lib/types/array.js @@ -1,8 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const DeepEqual = require('@hapi/hoek/lib/deepEqual'); -const Reach = require('@hapi/hoek/lib/reach'); +const { assert, deepEqual, reach } = require('@hapi/hoek'); const Any = require('./any'); const Common = require('../common'); @@ -415,7 +413,7 @@ module.exports = Any.extend({ method(enabled) { const value = enabled === undefined ? true : !!enabled; - Assert(!value || !this._flags._arrayItems, 'Cannot specify single rule when array has array items'); + assert(!value || !this._flags._arrayItems, 'Cannot specify single rule when array has array items'); return this.$_setFlag('single', value); } @@ -432,7 +430,7 @@ module.exports = Any.extend({ if (options.by) { settings.by = Compile.ref(options.by, { ancestor: 0 }); - Assert(!settings.by.ancestor, 'Cannot sort by ancestor'); + assert(!settings.by.ancestor, 'Cannot sort by ancestor'); } return this.$_addRule({ name: 'sort', args: { options: settings } }); @@ -472,7 +470,7 @@ module.exports = Any.extend({ unique: { method(comparator, options = {}) { - Assert(!comparator || typeof comparator === 'function' || typeof comparator === 'string', 'comparator must be a function or a string'); + assert(!comparator || typeof comparator === 'function' || typeof comparator === 'string', 'comparator must be a function or a string'); Common.assertOptions(options, ['ignoreUndefined', 'separator']); const rule = { name: 'unique', args: { options, comparator } }; @@ -501,13 +499,13 @@ module.exports = Any.extend({ custom: new Map() }; - const compare = comparator || DeepEqual; + const compare = comparator || deepEqual; const ignoreUndefined = options.ignoreUndefined; for (let i = 0; i < value.length; ++i) { - const item = path ? Reach(value[i], path) : value[i]; + const item = path ? reach(value[i], path) : value[i]; const records = comparator ? found.custom : found[typeof item]; - Assert(records, 'Failed to find unique map container for type', typeof item); + assert(records, 'Failed to find unique map container for type', typeof item); if (records instanceof Map) { const entries = records.entries(); @@ -724,7 +722,7 @@ internals.validateSingle = function (type, obj) { if (type.type === 'array' || type._flags._arrayItems) { - Assert(!obj._flags.single, 'Cannot specify array item with single rule enabled'); + assert(!obj._flags.single, 'Cannot specify array item with single rule enabled'); obj.$_setFlag('_arrayItems', true, { clone: false }); } }; diff --git a/lib/types/binary.js b/lib/types/binary.js index 9147166ab..64347d952 100755 --- a/lib/types/binary.js +++ b/lib/types/binary.js @@ -1,6 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); +const { assert } = require('@hapi/hoek'); const Any = require('./any'); const Common = require('../common'); @@ -35,7 +35,7 @@ module.exports = Any.extend({ encoding: { method(encoding) { - Assert(Buffer.isEncoding(encoding), 'Invalid encoding:', encoding); + assert(Buffer.isEncoding(encoding), 'Invalid encoding:', encoding); return this.$_setFlag('encoding', encoding); } diff --git a/lib/types/boolean.js b/lib/types/boolean.js index 686586648..2bb9bdf1d 100755 --- a/lib/types/boolean.js +++ b/lib/types/boolean.js @@ -1,6 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); +const { assert } = require('@hapi/hoek'); const Any = require('./any'); const Common = require('../common'); @@ -76,7 +76,7 @@ module.exports = Any.extend({ for (let i = 0; i < values.length; ++i) { const value = values[i]; - Assert(value !== undefined, 'Cannot call truthy with undefined'); + assert(value !== undefined, 'Cannot call truthy with undefined'); obj.$_terms.truthy.add(value); } @@ -95,7 +95,7 @@ module.exports = Any.extend({ for (let i = 0; i < values.length; ++i) { const value = values[i]; - Assert(value !== undefined, 'Cannot call falsy with undefined'); + assert(value !== undefined, 'Cannot call falsy with undefined'); obj.$_terms.falsy.add(value); } diff --git a/lib/types/date.js b/lib/types/date.js index b8206c6f8..8b9415964 100755 --- a/lib/types/date.js +++ b/lib/types/date.js @@ -1,6 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); +const { assert } = require('@hapi/hoek'); const Any = require('./any'); const Common = require('../common'); @@ -78,7 +78,7 @@ module.exports = Any.extend({ format: { method(format) { - Assert(['iso', 'javascript', 'unix'].includes(format), 'Unknown date format', format); + assert(['iso', 'javascript', 'unix'].includes(format), 'Unknown date format', format); return this.$_setFlag('format', format); } @@ -122,7 +122,7 @@ module.exports = Any.extend({ timestamp: { method(type = 'javascript') { - Assert(['javascript', 'unix'].includes(type), '"type" must be one of "javascript, unix"'); + assert(['javascript', 'unix'].includes(type), '"type" must be one of "javascript, unix"'); return this.format(type); } diff --git a/lib/types/function.js b/lib/types/function.js index eb8792e43..ebd5b3c37 100755 --- a/lib/types/function.js +++ b/lib/types/function.js @@ -1,6 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); +const { assert } = require('@hapi/hoek'); const Keys = require('./keys'); @@ -20,7 +20,7 @@ module.exports = Keys.extend({ arity: { method(n) { - Assert(Number.isSafeInteger(n) && n >= 0, 'n must be a positive integer'); + assert(Number.isSafeInteger(n) && n >= 0, 'n must be a positive integer'); return this.$_addRule({ name: 'arity', args: { n } }); }, @@ -52,7 +52,7 @@ module.exports = Keys.extend({ minArity: { method(n) { - Assert(Number.isSafeInteger(n) && n > 0, 'n must be a strict positive integer'); + assert(Number.isSafeInteger(n) && n > 0, 'n must be a strict positive integer'); return this.$_addRule({ name: 'minArity', args: { n } }); }, @@ -69,7 +69,7 @@ module.exports = Keys.extend({ maxArity: { method(n) { - Assert(Number.isSafeInteger(n) && n >= 0, 'n must be a positive integer'); + assert(Number.isSafeInteger(n) && n >= 0, 'n must be a positive integer'); return this.$_addRule({ name: 'maxArity', args: { n } }); }, diff --git a/lib/types/keys.js b/lib/types/keys.js index a907c4d00..de039a5c5 100755 --- a/lib/types/keys.js +++ b/lib/types/keys.js @@ -1,8 +1,6 @@ 'use strict'; -const ApplyToDefaults = require('@hapi/hoek/lib/applyToDefaults'); -const Assert = require('@hapi/hoek/lib/assert'); -const Clone = require('@hapi/hoek/lib/clone'); +const { applyToDefaults, assert, clone: Clone } = require('@hapi/hoek'); const Topo = require('@hapi/topo'); const Any = require('./any'); @@ -199,7 +197,7 @@ module.exports = Any.extend({ subject = Compile.ref(subject); } - Assert(message === undefined || typeof message === 'string', 'Message must be a string'); + assert(message === undefined || typeof message === 'string', 'Message must be a string'); schema = this.$_compile(schema, { appendPath: true }); @@ -225,7 +223,7 @@ module.exports = Any.extend({ instance: { method(constructor, name) { - Assert(typeof constructor === 'function', 'constructor must be a function'); + assert(typeof constructor === 'function', 'constructor must be a function'); name = name || constructor.name; @@ -245,8 +243,8 @@ module.exports = Any.extend({ keys: { method(schema) { - Assert(schema === undefined || typeof schema === 'object', 'Object schema must be a valid object'); - Assert(!Common.isSchema(schema), 'Object schema cannot be a joi schema'); + assert(schema === undefined || typeof schema === 'object', 'Object schema must be a valid object'); + assert(!Common.isSchema(schema), 'Object schema cannot be a joi schema'); const obj = this.clone(); @@ -337,11 +335,11 @@ module.exports = Any.extend({ pattern = this.$_compile(pattern, { appendPath: true }); } - Assert(schema !== undefined, 'Invalid rule'); + assert(schema !== undefined, 'Invalid rule'); Common.assertOptions(options, ['fallthrough', 'matches']); if (isRegExp) { - Assert(!pattern.flags.includes('g') && !pattern.flags.includes('y'), 'pattern should not use global or sticky mode'); + assert(!pattern.flags.includes('g') && !pattern.flags.includes('y'), 'pattern should not use global or sticky mode'); } schema = this.$_compile(schema, { appendPath: true }); @@ -402,9 +400,9 @@ module.exports = Any.extend({ rename: { method(from, to, options = {}) { - Assert(typeof from === 'string' || from instanceof RegExp, 'Rename missing the from argument'); - Assert(typeof to === 'string' || to instanceof Template, 'Invalid rename to argument'); - Assert(to !== from, 'Cannot rename key to same name:', from); + assert(typeof from === 'string' || from instanceof RegExp, 'Rename missing the from argument'); + assert(typeof to === 'string' || to instanceof Template, 'Invalid rename to argument'); + assert(to !== from, 'Cannot rename key to same name:', from); Common.assertOptions(options, ['alias', 'ignoreUndefined', 'override', 'multiple']); @@ -412,7 +410,7 @@ module.exports = Any.extend({ obj.$_terms.renames = obj.$_terms.renames || []; for (const rename of obj.$_terms.renames) { - Assert(rename.from !== from, 'Cannot rename the same key multiple times'); + assert(rename.from !== from, 'Cannot rename the same key multiple times'); } if (to instanceof Template) { @@ -422,7 +420,7 @@ module.exports = Any.extend({ obj.$_terms.renames.push({ from, to, - options: ApplyToDefaults(internals.renameDefaults, options) + options: applyToDefaults(internals.renameDefaults, options) }); return obj; @@ -589,7 +587,7 @@ internals.clone = function (value, prefs) { internals.dependency = function (schema, rel, key, peers, options) { - Assert(key === null || typeof key === 'string', rel, 'key must be a strings'); + assert(key === null || typeof key === 'string', rel, 'key must be a strings'); // Extract options from peers array @@ -606,7 +604,7 @@ internals.dependency = function (schema, rel, key, peers, options) { const separator = Common.default(options.separator, '.'); const paths = []; for (const peer of peers) { - Assert(typeof peer === 'string', rel, 'peers must be strings'); + assert(typeof peer === 'string', rel, 'peers must be strings'); paths.push(Compile.ref(peer, { separator, ancestor: 0, prefix: false })); } diff --git a/lib/types/link.js b/lib/types/link.js index d99d0025c..7ae8f383a 100755 --- a/lib/types/link.js +++ b/lib/types/link.js @@ -1,6 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); +const { assert } = require('@hapi/hoek'); const Any = require('./any'); const Common = require('../common'); @@ -31,7 +31,7 @@ module.exports = Any.extend({ validate(value, { schema, state, prefs }) { - Assert(schema.$_terms.link, 'Uninitialized link schema'); + assert(schema.$_terms.link, 'Uninitialized link schema'); const linked = internals.generate(schema, value, state, prefs); const ref = schema.$_terms.link[0].ref; @@ -48,12 +48,12 @@ module.exports = Any.extend({ ref: { method(ref) { - Assert(!this.$_terms.link, 'Cannot reinitialize schema'); + assert(!this.$_terms.link, 'Cannot reinitialize schema'); ref = Compile.ref(ref); - Assert(ref.type === 'value' || ref.type === 'local', 'Invalid reference type:', ref.type); - Assert(ref.type === 'local' || ref.ancestor === 'root' || ref.ancestor > 0, 'Link cannot reference itself'); + assert(ref.type === 'value' || ref.type === 'local', 'Invalid reference type:', ref.type); + assert(ref.type === 'local' || ref.ancestor === 'root' || ref.ancestor > 0, 'Link cannot reference itself'); const obj = this.clone(); obj.$_terms.link = [{ ref }]; @@ -73,9 +73,9 @@ module.exports = Any.extend({ concat(source) { - Assert(this.$_terms.link, 'Uninitialized link schema'); - Assert(Common.isSchema(source), 'Invalid schema object'); - Assert(source.type !== 'link', 'Cannot merge type link with another link'); + assert(this.$_terms.link, 'Uninitialized link schema'); + assert(Common.isSchema(source), 'Invalid schema object'); + assert(source.type !== 'link', 'Cannot merge type link with another link'); const obj = this.clone(); @@ -92,7 +92,7 @@ module.exports = Any.extend({ build(obj, desc) { - Assert(desc.link, 'Invalid link description missing link'); + assert(desc.link, 'Invalid link description missing link'); return obj.ref(desc.link); } } @@ -164,5 +164,5 @@ internals.assert = function (condition, message, ref, schema, state, prefs) { return; } - Assert(false, `"${Errors.label(schema._flags, state, prefs)}" contains link reference "${ref.display}" ${message}`); + assert(false, `"${Errors.label(schema._flags, state, prefs)}" contains link reference "${ref.display}" ${message}`); }; diff --git a/lib/types/number.js b/lib/types/number.js index 2031bb3e0..719b9678b 100755 --- a/lib/types/number.js +++ b/lib/types/number.js @@ -1,6 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); +const { assert } = require('@hapi/hoek'); const Any = require('./any'); const Common = require('../common'); @@ -224,7 +224,7 @@ module.exports = Any.extend({ precision: { method(limit) { - Assert(Number.isSafeInteger(limit), 'limit must be an integer'); + assert(Number.isSafeInteger(limit), 'limit must be an integer'); return this.$_addRule({ name: 'precision', args: { limit } }); }, @@ -244,7 +244,7 @@ module.exports = Any.extend({ sign: { method(sign) { - Assert(['negative', 'positive'].includes(sign), 'Invalid sign', sign); + assert(['negative', 'positive'].includes(sign), 'Invalid sign', sign); return this.$_addRule({ name: 'sign', args: { sign } }); }, @@ -263,7 +263,7 @@ module.exports = Any.extend({ unsafe: { method(enabled = true) { - Assert(typeof enabled === 'boolean', 'enabled must be a boolean'); + assert(typeof enabled === 'boolean', 'enabled must be a boolean'); return this.$_setFlag('unsafe', enabled); } diff --git a/lib/types/string.js b/lib/types/string.js index cdaffc409..f3a1ff85d 100755 --- a/lib/types/string.js +++ b/lib/types/string.js @@ -1,19 +1,15 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const Domain = require('@sideway/address/lib/domain'); -const Email = require('@sideway/address/lib/email'); -const Ip = require('@sideway/address/lib/ip'); -const EscapeRegex = require('@hapi/hoek/lib/escapeRegex'); -const Tlds = require('@sideway/address/lib/tlds'); -const Uri = require('@sideway/address/lib/uri'); +const { assert, escapeRegex } = require('@hapi/hoek'); +const { isDomainValid, isEmailValid, ipRegex, uriRegex } = require('@hapi/address'); +const Tlds = require('@hapi/tlds'); const Any = require('./any'); const Common = require('../common'); const internals = { - tlds: Tlds instanceof Set ? { tlds: { allow: Tlds, deny: null } } : false, // $lab:coverage:ignore$ + tlds: Tlds.tlds instanceof Set ? { tlds: { allow: Tlds.tlds, deny: null } } : false, // $lab:coverage:ignore$ base64Regex: { // paddingRequired true: { @@ -28,7 +24,7 @@ const internals = { }, dataUriRegex: /^data:[\w+.-]+\/[\w+.-]+;((charset=[\w-]+|base64),)?(.*)$/, hexRegex: /^[a-f0-9]+$/i, - ipRegex: Ip.regex({ cidr: 'forbidden' }).regex, + ipRegex: ipRegex({ cidr: 'forbidden' }).regex, isoDurationRegex: /^P(?!$)(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?$/, guidBrackets: { @@ -164,8 +160,8 @@ module.exports = Any.extend({ Common.assertOptions(options, ['paddingRequired', 'urlSafe']); options = { urlSafe: false, paddingRequired: true, ...options }; - Assert(typeof options.paddingRequired === 'boolean', 'paddingRequired must be boolean'); - Assert(typeof options.urlSafe === 'boolean', 'urlSafe must be boolean'); + assert(typeof options.paddingRequired === 'boolean', 'paddingRequired must be boolean'); + assert(typeof options.urlSafe === 'boolean', 'urlSafe must be boolean'); return this.$_addRule({ name: 'base64', args: { options } }); }, @@ -183,7 +179,7 @@ module.exports = Any.extend({ case: { method(direction) { - Assert(['lower', 'upper'].includes(direction), 'Invalid case:', direction); + assert(['lower', 'upper'].includes(direction), 'Invalid case:', direction); return this.$_addRule({ name: 'case', args: { direction } }); }, @@ -233,7 +229,7 @@ module.exports = Any.extend({ Common.assertOptions(options, ['paddingRequired']); options = { paddingRequired: true, ...options }; - Assert(typeof options.paddingRequired === 'boolean', 'paddingRequired must be boolean'); + assert(typeof options.paddingRequired === 'boolean', 'paddingRequired must be boolean'); return this.$_addRule({ name: 'dataUri', args: { options } }); }, @@ -264,7 +260,7 @@ module.exports = Any.extend({ method(options) { if (options) { - Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']); + Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'allowUnderscore', 'maxDomainSegments', 'minDomainSegments', 'tlds']); } const address = internals.addressOptions(options); @@ -272,7 +268,7 @@ module.exports = Any.extend({ }, validate(value, helpers, args, { address }) { - if (Domain.isValid(value, address)) { + if (isDomainValid(value, address)) { return value; } @@ -284,10 +280,10 @@ module.exports = Any.extend({ method(options = {}) { Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'ignoreLength', 'maxDomainSegments', 'minDomainSegments', 'multiple', 'separator', 'tlds']); - Assert(options.multiple === undefined || typeof options.multiple === 'boolean', 'multiple option must be an boolean'); + assert(options.multiple === undefined || typeof options.multiple === 'boolean', 'multiple option must be an boolean'); const address = internals.addressOptions(options); - const regex = new RegExp(`\\s*[${options.separator ? EscapeRegex(options.separator) : ','}]\\s*`); + const regex = new RegExp(`\\s*[${options.separator ? escapeRegex(options.separator) : ','}]\\s*`); return this.$_addRule({ name: 'email', args: { options }, regex, address }); }, @@ -296,7 +292,7 @@ module.exports = Any.extend({ const emails = options.multiple ? value.split(regex) : [value]; const invalids = []; for (const email of emails) { - if (!Email.isValid(email, address)) { + if (!isEmailValid(email, address)) { invalids.push(email); } } @@ -320,22 +316,22 @@ module.exports = Any.extend({ if (options.version) { const versions = [].concat(options.version); - Assert(versions.length >= 1, 'version must have at least 1 valid version specified'); + assert(versions.length >= 1, 'version must have at least 1 valid version specified'); const set = new Set(); for (let i = 0; i < versions.length; ++i) { const version = versions[i]; - Assert(typeof version === 'string', 'version at position ' + i + ' must be a string'); + assert(typeof version === 'string', 'version at position ' + i + ' must be a string'); const versionNumber = internals.guidVersions[version.toLowerCase()]; - Assert(versionNumber, 'version at position ' + i + ' must be one of ' + Object.keys(internals.guidVersions).join(', ')); - Assert(!set.has(versionNumber), 'version at position ' + i + ' must not be a duplicate'); + assert(versionNumber, 'version at position ' + i + ' must be one of ' + Object.keys(internals.guidVersions).join(', ')); + assert(!set.has(versionNumber), 'version at position ' + i + ' must not be a duplicate'); versionNumbers += versionNumber; set.add(versionNumber); } } - Assert(internals.guidSeparators.has(options.separator), 'separator must be one of true, false, "-", or ":"'); + assert(internals.guidSeparators.has(options.separator), 'separator must be one of true, false, "-", or ":"'); const separator = options.separator === undefined ? '[:-]?' : options.separator === true ? '[:-]' : options.separator === false ? '[]?' : `\\${options.separator}`; @@ -368,7 +364,7 @@ module.exports = Any.extend({ Common.assertOptions(options, ['byteAligned']); options = { byteAligned: false, ...options }; - Assert(typeof options.byteAligned === 'boolean', 'byteAligned must be boolean'); + assert(typeof options.byteAligned === 'boolean', 'byteAligned must be boolean'); return this.$_addRule({ name: 'hex', args: { options } }); }, @@ -395,7 +391,7 @@ module.exports = Any.extend({ }, validate(value, helpers) { - if (Domain.isValid(value, { minDomainSegments: 1 }) || + if (isDomainValid(value, { minDomainSegments: 1 }) || internals.ipRegex.test(value)) { return value; @@ -417,7 +413,7 @@ module.exports = Any.extend({ Common.assertOptions(options, ['cidr', 'version']); - const { cidr, versions, regex } = Ip.regex(options); + const { cidr, versions, regex } = ipRegex(options); const version = options.version ? versions : undefined; return this.$_addRule({ name: 'ip', args: { options: { cidr, version } }, regex }); }, @@ -516,7 +512,7 @@ module.exports = Any.extend({ normalize: { method(form = 'NFC') { - Assert(internals.normalizationForms.includes(form), 'normalization form must be one of ' + internals.normalizationForms.join(', ')); + assert(internals.normalizationForms.includes(form), 'normalization form must be one of ' + internals.normalizationForms.join(', ')); return this.$_addRule({ name: 'normalize', args: { form } }); }, @@ -535,8 +531,8 @@ module.exports = Any.extend({ alias: 'regex', method(regex, options = {}) { - Assert(regex instanceof RegExp, 'regex must be a RegExp'); - Assert(!regex.flags.includes('g') && !regex.flags.includes('y'), 'regex should not use global or sticky mode'); + assert(regex instanceof RegExp, 'regex must be a RegExp'); + assert(!regex.flags.includes('g') && !regex.flags.includes('y'), 'regex should not use global or sticky mode'); if (typeof options === 'string') { options = { name: options }; @@ -565,11 +561,11 @@ module.exports = Any.extend({ method(pattern, replacement) { if (typeof pattern === 'string') { - pattern = new RegExp(EscapeRegex(pattern), 'g'); + pattern = new RegExp(escapeRegex(pattern), 'g'); } - Assert(pattern instanceof RegExp, 'pattern must be a RegExp'); - Assert(typeof replacement === 'string', 'replacement must be a String'); + assert(pattern instanceof RegExp, 'pattern must be a RegExp'); + assert(typeof replacement === 'string', 'replacement must be a String'); const obj = this.clone(); @@ -600,7 +596,7 @@ module.exports = Any.extend({ trim: { method(enabled = true) { - Assert(typeof enabled === 'boolean', 'enabled must be a boolean'); + assert(typeof enabled === 'boolean', 'enabled must be a boolean'); return this.$_addRule({ name: 'trim', args: { enabled } }); }, @@ -620,7 +616,7 @@ module.exports = Any.extend({ truncate: { method(enabled = true) { - Assert(typeof enabled === 'boolean', 'enabled must be a boolean'); + assert(typeof enabled === 'boolean', 'enabled must be a boolean'); return this.$_setFlag('truncate', enabled); } @@ -642,7 +638,7 @@ module.exports = Any.extend({ Common.assertOptions(options.domain, ['allowFullyQualified', 'allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']); } - const { regex, scheme } = Uri.regex(options); + const { regex, scheme } = uriRegex(options); const domain = options.domain ? internals.addressOptions(options.domain) : null; return this.$_addRule({ name: 'uri', args: { options }, regex, domain, scheme }); }, @@ -657,7 +653,7 @@ module.exports = Any.extend({ const matched = match[1] || match[2]; if (domain && (!options.allowRelative || matched) && - !Domain.isValid(matched, domain)) { + !isDomainValid(matched, domain)) { return helpers.error('string.domain', { value: matched }); } @@ -738,12 +734,12 @@ internals.addressOptions = function (options) { // minDomainSegments - Assert(options.minDomainSegments === undefined || + assert(options.minDomainSegments === undefined || Number.isSafeInteger(options.minDomainSegments) && options.minDomainSegments > 0, 'minDomainSegments must be a positive integer'); // maxDomainSegments - Assert(options.maxDomainSegments === undefined || + assert(options.maxDomainSegments === undefined || Number.isSafeInteger(options.maxDomainSegments) && options.maxDomainSegments > 0, 'maxDomainSegments must be a positive integer'); // tlds @@ -755,11 +751,11 @@ internals.addressOptions = function (options) { if (options.tlds === true || options.tlds === undefined) { - Assert(internals.tlds, 'Built-in TLD list disabled'); + assert(internals.tlds, 'Built-in TLD list disabled'); return Object.assign({}, options, internals.tlds); } - Assert(typeof options.tlds === 'object', 'tlds must be true, false, or an object'); + assert(typeof options.tlds === 'object', 'tlds must be true, false, or an object'); const deny = options.tlds.deny; if (deny) { @@ -767,19 +763,19 @@ internals.addressOptions = function (options) { options = Object.assign({}, options, { tlds: { deny: new Set(deny) } }); } - Assert(options.tlds.deny instanceof Set, 'tlds.deny must be an array, Set, or boolean'); - Assert(!options.tlds.allow, 'Cannot specify both tlds.allow and tlds.deny lists'); + assert(options.tlds.deny instanceof Set, 'tlds.deny must be an array, Set, or boolean'); + assert(!options.tlds.allow, 'Cannot specify both tlds.allow and tlds.deny lists'); internals.validateTlds(options.tlds.deny, 'tlds.deny'); return options; } const allow = options.tlds.allow; if (!allow) { - return options; + return { ...options, tlds: false }; } if (allow === true) { - Assert(internals.tlds, 'Built-in TLD list disabled'); + assert(internals.tlds, 'Built-in TLD list disabled'); return Object.assign({}, options, internals.tlds); } @@ -787,7 +783,7 @@ internals.addressOptions = function (options) { options = Object.assign({}, options, { tlds: { allow: new Set(allow) } }); } - Assert(options.tlds.allow instanceof Set, 'tlds.allow must be an array, Set, or boolean'); + assert(options.tlds.allow instanceof Set, 'tlds.allow must be an array, Set, or boolean'); internals.validateTlds(options.tlds.allow, 'tlds.allow'); return options; }; @@ -796,7 +792,7 @@ internals.addressOptions = function (options) { internals.validateTlds = function (set, source) { for (const tld of set) { - Assert(Domain.isValid(tld, { minDomainSegments: 1, maxDomainSegments: 1 }), `${source} must contain valid top level domain names`); + assert(isDomainValid(tld, { minDomainSegments: 1, maxDomainSegments: 1 }), `${source} must contain valid top level domain names`); } }; @@ -822,7 +818,7 @@ internals.isoDate = function (value) { internals.length = function (schema, name, limit, operator, encoding) { - Assert(!encoding || Buffer && Buffer.isEncoding(encoding), 'Invalid encoding:', encoding); // $lab:coverage:ignore$ + assert(!encoding || Buffer && Buffer.isEncoding(encoding), 'Invalid encoding:', encoding); // $lab:coverage:ignore$ return schema.$_addRule({ name, method: 'length', args: { limit, encoding }, operator }); }; diff --git a/lib/types/symbol.js b/lib/types/symbol.js index eafe9ae53..55764abda 100755 --- a/lib/types/symbol.js +++ b/lib/types/symbol.js @@ -1,6 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); +const { assert } = require('@hapi/hoek'); const Any = require('./any'); @@ -62,17 +62,17 @@ module.exports = Any.extend({ iterable = Object.entries(iterable); } - Assert(iterable && iterable[Symbol.iterator], 'Iterable must be an iterable or object'); + assert(iterable && iterable[Symbol.iterator], 'Iterable must be an iterable or object'); const obj = this.clone(); const symbols = []; for (const entry of iterable) { - Assert(entry && entry[Symbol.iterator], 'Entry must be an iterable'); + assert(entry && entry[Symbol.iterator], 'Entry must be an iterable'); const [key, value] = entry; - Assert(typeof key !== 'object' && typeof key !== 'function' && typeof key !== 'symbol', 'Key must not be of type object, function, or Symbol'); - Assert(typeof value === 'symbol', 'Value must be a Symbol'); + assert(typeof key !== 'object' && typeof key !== 'function' && typeof key !== 'symbol', 'Key must not be of type object, function, or Symbol'); + assert(typeof value === 'symbol', 'Value must be a Symbol'); obj.$_terms.map.set(key, value); symbols.push(value); diff --git a/lib/validator.js b/lib/validator.js index cd29ed832..116b32ec4 100755 --- a/lib/validator.js +++ b/lib/validator.js @@ -1,9 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const Clone = require('@hapi/hoek/lib/clone'); -const Ignore = require('@hapi/hoek/lib/ignore'); -const Reach = require('@hapi/hoek/lib/reach'); +const { assert, clone, ignore, reach } = require('@hapi/hoek'); const Common = require('./common'); const Errors = require('./errors'); @@ -19,13 +16,13 @@ exports.entry = function (value, schema, prefs) { let settings = Common.defaults; if (prefs) { - Assert(prefs.warnings === undefined, 'Cannot override warnings preference in synchronous validation'); - Assert(prefs.artifacts === undefined, 'Cannot override artifacts preference in synchronous validation'); + assert(prefs.warnings === undefined, 'Cannot override warnings preference in synchronous validation'); + assert(prefs.artifacts === undefined, 'Cannot override artifacts preference in synchronous validation'); settings = Common.preferences(Common.defaults, prefs); } const result = internals.entry(value, schema, settings); - Assert(!result.mainstay.externals.length, 'Schema with external rules must use validateAsync()'); + assert(!result.mainstay.externals.length, 'Schema with external rules must use validateAsync()'); const outcome = { value: result.value }; if (result.error) { @@ -74,7 +71,7 @@ exports.entryAsync = async function (value, schema, prefs) { if (path.length) { key = path[path.length - 1]; - parent = Reach(root, path.slice(0, -1)); + parent = reach(root, path.slice(0, -1)); node = parent[key]; } @@ -162,7 +159,7 @@ internals.tracer = function (schema, prefs) { } if (prefs.debug) { - Assert(schema.$_root.trace, 'Debug mode not supported'); + assert(schema.$_root.trace, 'Debug mode not supported'); return { tracer: schema.$_root.trace()._register(schema), cleanup: true }; } @@ -478,7 +475,7 @@ internals.finalize = function (value, errors, helpers) { } for (const error of errors) { - Assert(error instanceof Error || error instanceof Errors.Report, 'error() must return an Error object'); + assert(error instanceof Error || error instanceof Errors.Report, 'error() must return an Error object'); } } else { @@ -590,7 +587,7 @@ internals.default = function (flag, value, errors, helpers) { } if (typeof source === 'function') { - const args = source.length ? [Clone(state.ancestors[0]), helpers] : []; + const args = source.length ? [clone(state.ancestors[0]), helpers] : []; try { return source(...args); @@ -613,7 +610,7 @@ internals.default = function (flag, value, errors, helpers) { return source.resolve(value, state, prefs); } - return Clone(source); + return clone(source); }; @@ -636,12 +633,12 @@ internals.trim = function (value, schema) { internals.ignore = { active: false, - debug: Ignore, - entry: Ignore, - filter: Ignore, - log: Ignore, - resolve: Ignore, - value: Ignore + debug: ignore, + entry: ignore, + filter: ignore, + log: ignore, + resolve: ignore, + value: ignore }; diff --git a/lib/values.js b/lib/values.js index bfdb90b41..663586a68 100755 --- a/lib/values.js +++ b/lib/values.js @@ -1,7 +1,6 @@ 'use strict'; -const Assert = require('@hapi/hoek/lib/assert'); -const DeepEqual = require('@hapi/hoek/lib/deepEqual'); +const { assert, deepEqual } = require('@hapi/hoek'); const Common = require('./common'); @@ -132,7 +131,7 @@ module.exports = internals.Values = class { if (typeof value === 'object') { for (const item of this._values) { - if (DeepEqual(item, value)) { + if (deepEqual(item, value)) { return { value: item }; } } @@ -165,7 +164,7 @@ module.exports = internals.Values = class { } } else { - if (DeepEqual(item, value)) { + if (deepEqual(item, value)) { return { value: item, ref }; } } @@ -209,7 +208,7 @@ module.exports = internals.Values = class { concat(source) { - Assert(!source._override, 'Cannot concat override set of values'); + assert(!source._override, 'Cannot concat override set of values'); const set = new internals.Values([...this._values, ...source._values], [...this._refs, ...source._refs]); set._override = this._override; diff --git a/package.json b/package.json index 637ea135c..f57890793 100755 --- a/package.json +++ b/package.json @@ -15,18 +15,19 @@ "validation" ], "dependencies": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.3", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" + "@hapi/hoek": "^11.0.2", + "@hapi/tlds": "^1.0.1", + "@hapi/topo": "^6.0.2", + "@hapi/address": "^5.1.1", + "@hapi/pinpoint": "^2.0.1", + "@hapi/formula": "^3.0.2" }, "devDependencies": { - "@hapi/bourne": "2.x.x", - "@hapi/code": "8.x.x", + "@hapi/bourne": "^3.0.0", + "@hapi/code": "^9.0.3", "@hapi/joi-legacy-test": "npm:@hapi/joi@15.x.x", - "@hapi/lab": "^25.0.1", - "@types/node": "^14.18.24", + "@hapi/lab": "^25.1.2", + "@types/node": "^14.18.37", "typescript": "4.3.x" }, "scripts": { diff --git a/test/trace.js b/test/trace.js index 360dbb76c..dadc9e7f8 100755 --- a/test/trace.js +++ b/test/trace.js @@ -3,7 +3,7 @@ const Code = require('@hapi/code'); const Lab = require('@hapi/lab'); const Joi = require('..'); -const Pinpoint = require('@sideway/pinpoint'); +const Pinpoint = require('@hapi/pinpoint'); const internals = {}; diff --git a/test/types/string.js b/test/types/string.js index fdc34744a..9b3c40592 100755 --- a/test/types/string.js +++ b/test/types/string.js @@ -1334,6 +1334,37 @@ describe('string', () => { context: { value: 'something', label: 'item', key: 'item' } }]]); }); + + it('validates domain with underscores', () => { + + const validSchema = Joi.string().domain({ allowUnderscore: true }); + Helper.validate(validSchema, [ + ['_acme-challenge.example.com', true], + ['_abc.example.com', true] + ]); + + const invalidSchema = Joi.string().domain(); + Helper.validate(invalidSchema, [ + ['_acme-challenge.example.com', false, { + context: { + label: 'value', + value: '_acme-challenge.example.com' + }, + message: '"value" must contain a valid domain name', + path: [], + type: 'string.domain' + }], + ['_abc.example.com', false, { + context: { + label: 'value', + value: '_abc.example.com' + }, + message: '"value" must contain a valid domain name', + path: [], + type: 'string.domain' + }] + ]); + }); }); describe('email()', () => { @@ -4589,7 +4620,7 @@ describe('string', () => { it('throws when options.cidr is not a string', () => { - expect(() => Joi.string().ip({ cidr: 42 })).to.throw('options.cidr must be a string'); + expect(() => Joi.string().ip({ cidr: 42 })).to.throw('options.cidr must be one of required, optional, forbidden'); }); it('throws when options.cidr is not a valid value', () => {