Comparing version 17.1.1 to 17.2.0
@@ -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 @@ |
@@ -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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
512628
36
9520
0
14
Updated@hapi/address@^4.1.0