Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

joi

Package Overview
Dependencies
Maintainers
1
Versions
238
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

joi - npm Package Compare versions

Comparing version 17.1.1 to 17.2.0

lib/index.d.ts

35

lib/base.js

@@ -35,2 +35,7 @@ 'use strict';

this._definition = {};
this._reset();
}
_reset() {
this._ids = new Modify.Ids();

@@ -89,2 +94,10 @@ this._preferences = null;

artifact(id) {
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) {

@@ -321,2 +334,3 @@

Assert(!this._cache, 'Cannot override schema cache');
Assert(this._flags.artifact === undefined, 'Cannot cache a rule with an artifact');

@@ -755,2 +769,7 @@ const obj = this.clone();

$_parent(method, ...args) {
return this[method][Common.symbols.parent].call(this, ...args);
}
$_validate(value, state, prefs) {

@@ -787,2 +806,4 @@

// Backwards compatibility
target.$_super = {};

@@ -796,2 +817,16 @@ for (const override in this.$_super) {

_bare() {
const obj = this.clone();
obj._reset();
const terms = obj._definition.terms;
for (const name in terms) {
const term = terms[name];
obj.$_terms[name] = term.init;
}
return obj.$_mutateRebuild();
}
_default(flag, value, options = {}) {

@@ -798,0 +833,0 @@

7

lib/common.js

@@ -23,2 +23,3 @@ 'use strict';

allowUnknown: false,
artifacts: false,
cache: true,

@@ -54,8 +55,10 @@ context: null,

deepDefault: Symbol('deepDefault'),
errors: Symbol('errors'),
literal: Symbol('literal'),
override: Symbol('override'),
parent: Symbol('parent'),
prefs: Symbol('prefs'),
ref: Symbol('ref'),
values: Symbol('values'),
template: Symbol('template')
template: Symbol('template'),
values: Symbol('values')
};

@@ -62,0 +65,0 @@

@@ -159,6 +159,7 @@ 'use strict';

prototype._super = base;
schema.$_super = {};
schema.$_super = {}; // Backwards compatibility
for (const override in def.overrides) {
Assert(base[override], 'Cannot override missing', override);
schema.$_super[override] = base[override].bind(schema);
def.overrides[override][Common.symbols.parent] = base[override];
schema.$_super[override] = base[override].bind(schema); // Backwards compatibility
}

@@ -165,0 +166,0 @@

@@ -259,3 +259,3 @@ 'use strict';

let schema = this.joi[desc.type]();
let schema = this.joi[desc.type]()._bare();
const def = schema._definition;

@@ -262,0 +262,0 @@

@@ -28,3 +28,3 @@ 'use strict';

Assert(typeof key === 'string', 'Invalid reference key:', key);
Common.assertOptions(options, ['adjust', 'ancestor', 'in', 'iterables', 'map', 'prefix', 'separator']);
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');

@@ -81,3 +81,3 @@

return exports.create(key, Object.assign({}, options, { in: true }));
return exports.create(key, { ...options, in: true });
};

@@ -98,4 +98,4 @@

Common.assertOptions(options, [
'adjust', 'ancestor', 'in', 'iterables', 'map', 'path', 'separator', 'type', // Copied
'depth', 'key', 'root', 'display' // Overridden
'adjust', 'ancestor', 'in', 'iterables', 'map', 'path', 'render', 'separator', 'type', // Copied
'depth', 'key', 'root', 'display' // Overridden
]);

@@ -217,4 +217,6 @@

for (const key of ['adjust', 'iterables']) {
if (this[key] !== null) {
for (const key of ['adjust', 'iterables', 'render']) {
if (this[key] !== null &&
this[key] !== undefined) {
ref[key] = this[key];

@@ -221,0 +223,0 @@ }

@@ -20,2 +20,3 @@ 'use strict';

abortEarly: Joi.boolean(),
artifacts: Joi.boolean(),
cache: Joi.boolean(),

@@ -93,2 +94,6 @@ context: Joi.object(),

args: Joi.function(),
cast: Joi.object().pattern(internals.nameRx, Joi.object({
from: Joi.function().maxArity(1).required(),
to: Joi.function().minArity(1).maxArity(2).required()
})),
base: Joi.object().schema()

@@ -162,3 +167,4 @@ .when('type', { is: Joi.object().regex(), then: Joi.forbidden() }),

iterables: Joi.boolean(),
in: Joi.boolean()
in: Joi.boolean(),
render: Joi.boolean()
})

@@ -250,2 +256,3 @@ .required()

abortEarly: Joi.boolean(),
artifacts: Joi.boolean(),
cache: Joi.boolean(),

@@ -252,0 +259,0 @@ convert: Joi.boolean(),

@@ -81,4 +81,9 @@ 'use strict';

const variable = part.slice(raw ? 0 : 1, end);
const dynamic = this._ref(internals.decode(variable), raw);
let variable = part.slice(raw ? 0 : 1, end);
const wrapped = variable[0] === ':';
if (wrapped) {
variable = variable.slice(1);
}
const dynamic = this._ref(internals.decode(variable), { raw, wrapped });
processed.push(dynamic);

@@ -188,7 +193,6 @@ if (typeof dynamic !== 'string') {

const rendered = this._part(part, /* context -> [*/ value, state, prefs, local, options /*] */);
const string = internals.stringify(rendered, prefs, options.errors);
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 ends = part.ref && part.ref.type === 'local' && part.ref.key === 'label' && prefs.errors.wrap.label;
parts.push(internals.wrap(result, ends));
parts.push(internals.wrap(result, part.wrapped && prefs.errors.wrap.label));
}

@@ -201,3 +205,3 @@ }

_ref(content, raw) {
_ref(content, { raw, wrapped }) {

@@ -222,3 +226,4 @@ const refs = [];

if (formula.single.type === 'reference') {
return { ref: refs[0], raw, refs };
const ref = refs[0];
return { ref, raw, refs, wrapped: wrapped || ref.type === 'local' && ref.key === 'label' };
}

@@ -309,6 +314,14 @@

internals.stringify = function (value, prefs, options) {
internals.stringify = function (value, original, state, prefs, local, options) {
const type = typeof value;
let skipWrap = false;
if (Ref.isRef(value) &&
value.render) {
skipWrap = value.in;
value = value.resolve(original, state, prefs, local, { in: value.in, ...options });
}
if (value === null) {

@@ -352,5 +365,9 @@ return 'null';

for (const item of value) {
partial = partial + (partial.length ? ', ' : '') + internals.stringify(item, prefs, options);
partial = partial + (partial.length ? ', ' : '') + internals.stringify(item, original, state, prefs, local, options);
}
if (skipWrap) {
return partial;
}
return internals.wrap(partial, prefs.errors.wrap.array);

@@ -357,0 +374,0 @@ };

@@ -186,3 +186,3 @@ 'use strict';

const obj = this.$_super.label(name);
const obj = this.$_parent('label', name);
const each = (item, source) => (source.path[0] !== 'is' ? item.label(name) : undefined);

@@ -189,0 +189,0 @@ return obj.$_modify({ each, ref: false });

@@ -170,3 +170,3 @@ 'use strict';

'any.only': '{{#label}} must be {if(#valids.length == 1, "", "one of ")}{{#valids}}',
'any.ref': '{{#label}} {{#arg}} references "{{#ref}}" which {{#reason}}',
'any.ref': '{{#label}} {{#arg}} references {{:#ref}} which {{#reason}}',
'any.required': '{{#label}} is required',

@@ -173,0 +173,0 @@ 'any.unknown': '{{#label}} is not allowed'

@@ -117,3 +117,3 @@ 'use strict';

},
validate(value, { schema, error, state, prefs }) {
validate(value, { schema, error, state, prefs, errorsArray }) {

@@ -127,3 +127,4 @@ const requireds = schema.$_terms._requireds.slice();

const errors = [];
const errors = errorsArray();
let il = value.length;

@@ -616,3 +617,3 @@ for (let i = 0; i < il; ++i) {

'array.excludes': '{{#label}} contains an excluded value',
'array.hasKnown': '{{#label}} does not contain at least one required match for type "{#patternLabel}"',
'array.hasKnown': '{{#label}} does not contain at least one required match for type {:#patternLabel}',
'array.hasUnknown': '{{#label}} does not contain at least one required match',

@@ -619,0 +620,0 @@ 'array.includes': '{{#label}} does not match any of the allowed types',

@@ -152,6 +152,6 @@ 'use strict';

'date.format': '{{#label}} must be in {msg("date.format." + #format) || #format} format',
'date.greater': '{{#label}} must be greater than "{{#limit}}"',
'date.less': '{{#label}} must be less than "{{#limit}}"',
'date.max': '{{#label}} must be less than or equal to "{{#limit}}"',
'date.min': '{{#label}} must be larger than or equal to "{{#limit}}"',
'date.greater': '{{#label}} must be greater than {{:#limit}}',
'date.less': '{{#label}} must be less than {{:#limit}}',
'date.max': '{{#label}} must be less than or equal to {{:#limit}}',
'date.min': '{{#label}} must be greater than or equal to {{:#limit}}',

@@ -158,0 +158,0 @@ // Messages used in date.format

@@ -30,2 +30,3 @@ 'use strict';

properties: {
typeof: 'object'

@@ -482,3 +483,3 @@ },

return this.$_super.default(value, options);
return this.$_parent('default', value, options);
}

@@ -533,3 +534,3 @@ },

'object.base': '{{#label}} must be of type {{#type}}',
'object.instance': '{{#label}} must be an instance of "{{#type}}"',
'object.instance': '{{#label}} must be an instance of {{:#type}}',
'object.length': '{{#label}} must have {{#limit}} key{if(#limit == 1, "", "s")}',

@@ -539,3 +540,3 @@ 'object.max': '{{#label}} must have less than or equal to {{#limit}} key{if(#limit == 1, "", "s")}',

'object.missing': '{{#label}} must contain at least one of {{#peersWithLabels}}',
'object.nand': '"{{#mainWithLabel}}" must not exist simultaneously with {{#peersWithLabels}}',
'object.nand': '{{:#mainWithLabel}} must not exist simultaneously with {{#peersWithLabels}}',
'object.oxor': '{{#label}} contains a conflict between optional exclusive peers {{#peersWithLabels}}',

@@ -545,8 +546,8 @@ 'object.pattern.match': '{{#label}} keys failed to match pattern requirements',

'object.regex': '{{#label}} must be a RegExp object',
'object.rename.multiple': '{{#label}} cannot rename "{{#from}}" because multiple renames are disabled and another key was already renamed to "{{#to}}"',
'object.rename.override': '{{#label}} cannot rename "{{#from}}" because override is disabled and target "{{#to}}" exists',
'object.rename.multiple': '{{#label}} cannot rename {{:#from}} because multiple renames are disabled and another key was already renamed to {{:#to}}',
'object.rename.override': '{{#label}} cannot rename {{:#from}} because override is disabled and target {{:#to}} exists',
'object.schema': '{{#label}} must be a Joi schema of {{#type}} type',
'object.unknown': '{{#label}} is not allowed',
'object.with': '"{{#mainWithLabel}}" missing required peer "{{#peerWithLabel}}"',
'object.without': '"{{#mainWithLabel}}" conflict with forbidden peer "{{#peerWithLabel}}"',
'object.with': '{{:#mainWithLabel}} missing required peer {{:#peerWithLabel}}',
'object.without': '{{:#mainWithLabel}} conflict with forbidden peer {{:#peerWithLabel}}',
'object.xor': '{{#label}} contains a conflict between exclusive peers {{#peersWithLabels}}'

@@ -553,0 +554,0 @@ }

@@ -287,3 +287,3 @@ 'use strict';

'number.max': '{{#label}} must be less than or equal to {{#limit}}',
'number.min': '{{#label}} must be larger than or equal to {{#limit}}',
'number.min': '{{#label}} must be greater than or equal to {{#limit}}',
'number.multiple': '{{#label}} must be a multiple of {{#multiple}}',

@@ -316,6 +316,10 @@ 'number.negative': '{{#label}} must be a negative number',

str = str
// Remove leading plus signs
.replace(/^\+/, '')
.replace(/\.0+$/, '')
// Remove trailing zeros if there is a decimal point and unecessary decimal points
.replace(/\.0*$/, '')
// Add a integer 0 if the numbers starts with a decimal point
.replace(/^(-?)\.([^\.]*)$/, '$10.$2')
.replace(/^(-?)0+([1-9])/, '$1$2');
// Remove leading zeros
.replace(/^(-?)0+([0-9])/, '$1$2');

@@ -322,0 +326,0 @@ if (str.includes('.') &&

@@ -44,4 +44,4 @@ 'use strict';

},
guidSeparators: new Set([undefined, true, false, '-', ':']),
cidrPresences: ['required', 'optional', 'forbidden'],
normalizationForms: ['NFC', 'NFD', 'NFKC', 'NFKD']

@@ -261,3 +261,3 @@ };

if (options) {
Common.assertOptions(options, ['allowUnicode', 'minDomainSegments', 'tlds']);
Common.assertOptions(options, ['allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']);
}

@@ -281,3 +281,3 @@

Common.assertOptions(options, ['allowUnicode', 'ignoreLength', 'minDomainSegments', 'multiple', 'separator', 'tlds']);
Common.assertOptions(options, ['allowUnicode', 'ignoreLength', 'maxDomainSegments', 'minDomainSegments', 'multiple', 'separator', 'tlds']);
Assert(options.multiple === undefined || typeof options.multiple === 'boolean', 'multiple option must be an boolean');

@@ -312,3 +312,3 @@

Common.assertOptions(options, ['version']);
Common.assertOptions(options, ['version', 'separator']);

@@ -335,4 +335,9 @@ let versionNumbers = '';

const regex = new RegExp(`^([\\[{\\(]?)[0-9A-F]{8}([:-]?)[0-9A-F]{4}\\2?[${versionNumbers || '0-9A-F'}][0-9A-F]{3}\\2?[${versionNumbers ? '89AB' : '0-9A-F'}][0-9A-F]{3}\\2?[0-9A-F]{12}([\\]}\\)]?)$`, 'i');
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}`;
const regex = new RegExp(`^([\\[{\\(]?)[0-9A-F]{8}(${separator})[0-9A-F]{4}\\2?[${versionNumbers || '0-9A-F'}][0-9A-F]{3}\\2?[${versionNumbers ? '89AB' : '0-9A-F'}][0-9A-F]{3}\\2?[0-9A-F]{12}([\\]}\\)]?)$`, 'i');
return this.$_addRule({ name: 'guid', args: { options }, regex });

@@ -635,3 +640,3 @@ },

if (options.domain) {
Common.assertOptions(options.domain, ['allowUnicode', 'minDomainSegments', 'tlds']);
Common.assertOptions(options.domain, ['allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']);
}

@@ -711,6 +716,6 @@

'string.token': '{{#label}} must only contain alpha-numeric and underscore characters',
'string.pattern.base': '{{#label}} with value "{[.]}" fails to match the required pattern: {{#regex}}',
'string.pattern.name': '{{#label}} with value "{[.]}" fails to match the {{#name}} pattern',
'string.pattern.invert.base': '{{#label}} with value "{[.]}" matches the inverted pattern: {{#regex}}',
'string.pattern.invert.name': '{{#label}} with value "{[.]}" matches the inverted {{#name}} pattern',
'string.pattern.base': '{{#label}} with value {:[.]} fails to match the required pattern: {{#regex}}',
'string.pattern.name': '{{#label}} with value {:[.]} fails to match the {{#name}} pattern',
'string.pattern.invert.base': '{{#label}} with value {:[.]} matches the inverted pattern: {{#regex}}',
'string.pattern.invert.name': '{{#label}} with value {:[.]} matches the inverted {{#name}} pattern',
'string.trim': '{{#label}} must not have leading or trailing whitespace',

@@ -738,2 +743,7 @@ 'string.uri': '{{#label}} must be a valid uri',

// maxDomainSegments
Assert(options.maxDomainSegments === undefined ||
Number.isSafeInteger(options.maxDomainSegments) && options.maxDomainSegments > 0, 'maxDomainSegments must be a positive integer');
// tlds

@@ -762,2 +772,3 @@

Assert(!options.tlds.allow, 'Cannot specify both tlds.allow and tlds.deny lists');
internals.validateTlds(options.tlds.deny, 'tlds.deny');
return options;

@@ -781,2 +792,3 @@ }

Assert(options.tlds.allow instanceof Set, 'tlds.allow must be an array, Set, or boolean');
internals.validateTlds(options.tlds.allow, 'tlds.allow');
return options;

@@ -786,2 +798,10 @@ };

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`);
}
};
internals.isoDate = function (value) {

@@ -793,2 +813,6 @@

if (/.*T.*[+-]\d\d$/.test(value)) { // Add missing trailing zeros to timeshift
value += '00';
}
const date = new Date(value);

@@ -795,0 +819,0 @@ if (isNaN(date.getTime())) {

@@ -23,2 +23,3 @@ 'use strict';

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);

@@ -43,2 +44,6 @@ }

if (result.mainstay.artifacts) {
outcome.artifacts = result.mainstay.artifacts;
}
return outcome;

@@ -103,3 +108,4 @@ };

if (!settings.warnings &&
!settings.debug) {
!settings.debug &&
!settings.artifacts) {

@@ -118,2 +124,6 @@ return result.value;

if (mainstay.artifacts) {
outcome.artifacts = mainstay.artifacts;
}
return outcome;

@@ -197,2 +207,3 @@ };

error: createError,
errorsArray: internals.errorsArray,
warn: (code, local, localState) => state.mainstay.warnings.push(createError(code, local, localState)),

@@ -252,3 +263,3 @@ message: (messages, local) => schema.$_createError('custom', value, local, state, prefs, { messages })

const presence = overrides.presence || schema._flags.presence || (schema._flags._endedSwitch ? 'ignore' : prefs.presence);
const presence = overrides.presence || schema._flags.presence || (schema._flags._endedSwitch ? null : prefs.presence);
if (value === undefined) {

@@ -425,3 +436,3 @@ if (presence === 'forbidden') {

if (Array.isArray(ret) &&
(ret[0] instanceof Errors.Report || ret[0] instanceof Error)) {
ret[Common.symbols.errors]) {

@@ -533,2 +544,16 @@ ret.forEach((report) => internals.error(report, rule));

// Artifacts
if (value !== undefined &&
!result.errors &&
schema._flags.artifact !== undefined) {
state.mainstay.artifacts = state.mainstay.artifacts || new Map();
if (!state.mainstay.artifacts.has(schema._flags.artifact)) {
state.mainstay.artifacts.set(schema._flags.artifact, []);
}
state.mainstay.artifacts.get(schema._flags.artifact).push(state.path);
}
return result;

@@ -626,1 +651,9 @@ };

};
internals.errorsArray = function () {
const errors = [];
errors[Common.symbols.errors] = true;
return errors;
};
{
"name": "joi",
"description": "Object schema validation",
"version": "17.1.1",
"repository": "git://github.com/sideway/joi",
"main": "lib/index.js",
"browser": "dist/joi-browser.min.js",
"files": [
"lib/**/*",
"dist/*"
],
"keywords": [
"schema",
"validation"
],
"dependencies": {
"@hapi/address": "^4.0.1",
"@hapi/formula": "^2.0.0",
"@hapi/hoek": "^9.0.0",
"@hapi/pinpoint": "^2.0.0",
"@hapi/topo": "^5.0.0"
},
"devDependencies": {
"@hapi/bourne": "2.x.x",
"@hapi/code": "8.x.x",
"@hapi/lab": "22.x.x",
"@hapi/joi-legacy-test": "npm:@hapi/joi@15.x.x"
},
"scripts": {
"prepublishOnly": "cd browser && npm install && npm run build",
"test": "lab -t 100 -a @hapi/code -L",
"test-cov-html": "lab -r html -o coverage.html -a @hapi/code"
},
"license": "BSD-3-Clause"
"name": "joi",
"description": "Object schema validation",
"version": "17.2.0",
"repository": "git://github.com/sideway/joi",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"browser": "dist/joi-browser.min.js",
"files": [
"lib/**/*",
"dist/*"
],
"keywords": [
"schema",
"validation"
],
"dependencies": {
"@hapi/address": "^4.1.0",
"@hapi/formula": "^2.0.0",
"@hapi/hoek": "^9.0.0",
"@hapi/pinpoint": "^2.0.0",
"@hapi/topo": "^5.0.0"
},
"devDependencies": {
"@hapi/bourne": "2.x.x",
"@hapi/code": "8.x.x",
"@hapi/lab": "23.x.x",
"@hapi/joi-legacy-test": "npm:@hapi/joi@15.x.x"
},
"scripts": {
"prepublishOnly": "cd browser && npm install && npm run build",
"test": "lab -t 100 -a @hapi/code -L -Y",
"test-cov-html": "lab -r html -o coverage.html -a @hapi/code"
},
"license": "BSD-3-Clause"
}

@@ -1,9 +0,5 @@

<a href="https://hapi.dev"><img src="https://raw.githubusercontent.com/hapijs/assets/master/images/family.png" width="180px" align="right" /></a>
# joi
# @hapi/joi
#### The most powerful schema description language and data validator for JavaScript.
**joi** is part of the **hapi** ecosystem and was designed to work seamlessly with the [hapi web framework](https://hapi.dev) and its other components (but works great on its own or with other frameworks). If you are using a different web framework and find this module useful, check out [hapi](https://hapi.dev) – they work even better together.
### Visit the [hapi.dev](https://hapi.dev) Developer Portal for tutorials, documentation, and support

@@ -10,0 +6,0 @@

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc