mirror of
https://github.com/idanoo/GoScrobble
synced 2025-07-05 23:52:18 +00:00
0.2.0 - Mid migration
This commit is contained in:
parent
139e6a915e
commit
7e38fdbd7d
42393 changed files with 5358157 additions and 62 deletions
59
web/node_modules/@hapi/joi/lib/cast.js
generated
vendored
Executable file
59
web/node_modules/@hapi/joi/lib/cast.js
generated
vendored
Executable file
|
@ -0,0 +1,59 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Ref = require('./ref');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
exports.schema = function (Joi, config) {
|
||||
|
||||
if (config !== undefined && config !== null && typeof config === 'object') {
|
||||
|
||||
if (config.isJoi) {
|
||||
return config;
|
||||
}
|
||||
|
||||
if (Array.isArray(config)) {
|
||||
return Joi.alternatives().try(config);
|
||||
}
|
||||
|
||||
if (config instanceof RegExp) {
|
||||
return Joi.string().regex(config);
|
||||
}
|
||||
|
||||
if (config instanceof Date) {
|
||||
return Joi.date().valid(config);
|
||||
}
|
||||
|
||||
return Joi.object().keys(config);
|
||||
}
|
||||
|
||||
if (typeof config === 'string') {
|
||||
return Joi.string().valid(config);
|
||||
}
|
||||
|
||||
if (typeof config === 'number') {
|
||||
return Joi.number().valid(config);
|
||||
}
|
||||
|
||||
if (typeof config === 'boolean') {
|
||||
return Joi.boolean().valid(config);
|
||||
}
|
||||
|
||||
if (Ref.isRef(config)) {
|
||||
return Joi.valid(config);
|
||||
}
|
||||
|
||||
Hoek.assert(config === null, 'Invalid schema content:', config);
|
||||
|
||||
return Joi.valid(null);
|
||||
};
|
||||
|
||||
|
||||
exports.ref = function (id) {
|
||||
|
||||
return Ref.isRef(id) ? id : Ref.create(id);
|
||||
};
|
372
web/node_modules/@hapi/joi/lib/errors.js
generated
vendored
Executable file
372
web/node_modules/@hapi/joi/lib/errors.js
generated
vendored
Executable file
|
@ -0,0 +1,372 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Language = require('./language');
|
||||
|
||||
|
||||
const internals = {
|
||||
annotations: Symbol('joi-annotations')
|
||||
};
|
||||
|
||||
|
||||
internals.stringify = function (value, wrapArrays) {
|
||||
|
||||
const type = typeof value;
|
||||
|
||||
if (value === null) {
|
||||
return 'null';
|
||||
}
|
||||
|
||||
if (type === 'string') {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value instanceof exports.Err || type === 'function' || type === 'symbol') {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
if (type === 'object') {
|
||||
if (Array.isArray(value)) {
|
||||
let partial = '';
|
||||
|
||||
for (let i = 0; i < value.length; ++i) {
|
||||
partial = partial + (partial.length ? ', ' : '') + internals.stringify(value[i], wrapArrays);
|
||||
}
|
||||
|
||||
return wrapArrays ? '[' + partial + ']' : partial;
|
||||
}
|
||||
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
return JSON.stringify(value);
|
||||
};
|
||||
|
||||
|
||||
exports.Err = class {
|
||||
|
||||
constructor(type, context, state, options, flags, message, template) {
|
||||
|
||||
this.isJoi = true;
|
||||
this.type = type;
|
||||
this.context = context || {};
|
||||
this.context.key = state.path[state.path.length - 1];
|
||||
this.context.label = state.key;
|
||||
this.path = state.path;
|
||||
this.options = options;
|
||||
this.flags = flags;
|
||||
this.message = message;
|
||||
this.template = template;
|
||||
|
||||
const localized = this.options.language;
|
||||
|
||||
if (this.flags.label) {
|
||||
this.context.label = this.flags.label;
|
||||
}
|
||||
else if (localized && // language can be null for arrays exclusion check
|
||||
(this.context.label === '' ||
|
||||
this.context.label === null)) {
|
||||
this.context.label = localized.root || Language.errors.root;
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
if (this.message) {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
let format;
|
||||
|
||||
if (this.template) {
|
||||
format = this.template;
|
||||
}
|
||||
|
||||
const localized = this.options.language;
|
||||
|
||||
format = format || Hoek.reach(localized, this.type) || Hoek.reach(Language.errors, this.type);
|
||||
|
||||
if (format === undefined) {
|
||||
return `Error code "${this.type}" is not defined, your custom type is missing the correct language definition`;
|
||||
}
|
||||
|
||||
let wrapArrays = Hoek.reach(localized, 'messages.wrapArrays');
|
||||
if (typeof wrapArrays !== 'boolean') {
|
||||
wrapArrays = Language.errors.messages.wrapArrays;
|
||||
}
|
||||
|
||||
if (format === null) {
|
||||
const childrenString = internals.stringify(this.context.reason, wrapArrays);
|
||||
if (wrapArrays) {
|
||||
return childrenString.slice(1, -1);
|
||||
}
|
||||
|
||||
return childrenString;
|
||||
}
|
||||
|
||||
const hasKey = /{{!?label}}/.test(format);
|
||||
const skipKey = format.length > 2 && format[0] === '!' && format[1] === '!';
|
||||
|
||||
if (skipKey) {
|
||||
format = format.slice(2);
|
||||
}
|
||||
|
||||
if (!hasKey && !skipKey) {
|
||||
const localizedKey = Hoek.reach(localized, 'key');
|
||||
if (typeof localizedKey === 'string') {
|
||||
format = localizedKey + format;
|
||||
}
|
||||
else {
|
||||
format = Hoek.reach(Language.errors, 'key') + format;
|
||||
}
|
||||
}
|
||||
|
||||
const message = format.replace(/{{(!?)([^}]+)}}/g, ($0, isSecure, name) => {
|
||||
|
||||
const value = Hoek.reach(this.context, name);
|
||||
const normalized = internals.stringify(value, wrapArrays);
|
||||
return (isSecure && this.options.escapeHtml ? Hoek.escapeHtml(normalized) : normalized);
|
||||
});
|
||||
|
||||
this.toString = () => message; // Persist result of last toString call, it won't change
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
exports.create = function (type, context, state, options, flags, message, template) {
|
||||
|
||||
return new exports.Err(type, context, state, options, flags, message, template);
|
||||
};
|
||||
|
||||
|
||||
exports.process = function (errors, object) {
|
||||
|
||||
if (!errors) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Construct error
|
||||
|
||||
let message = '';
|
||||
const details = [];
|
||||
|
||||
const processErrors = function (localErrors, parent, overrideMessage) {
|
||||
|
||||
for (let i = 0; i < localErrors.length; ++i) {
|
||||
const item = localErrors[i];
|
||||
|
||||
if (item instanceof Error) {
|
||||
return item;
|
||||
}
|
||||
|
||||
if (item.flags.error && typeof item.flags.error !== 'function') {
|
||||
if (!item.flags.selfError || !item.context.reason) {
|
||||
return item.flags.error;
|
||||
}
|
||||
}
|
||||
|
||||
let itemMessage;
|
||||
if (parent === undefined) {
|
||||
itemMessage = item.toString();
|
||||
message = message + (message ? '. ' : '') + itemMessage;
|
||||
}
|
||||
|
||||
// Do not push intermediate errors, we're only interested in leafs
|
||||
|
||||
if (item.context.reason) {
|
||||
const override = processErrors(item.context.reason, item.path, item.type === 'override' ? item.message : null);
|
||||
if (override) {
|
||||
return override;
|
||||
}
|
||||
}
|
||||
else {
|
||||
details.push({
|
||||
message: overrideMessage || itemMessage || item.toString(),
|
||||
path: item.path,
|
||||
type: item.type,
|
||||
context: item.context
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const override = processErrors(errors);
|
||||
if (override) {
|
||||
return override;
|
||||
}
|
||||
|
||||
const error = new Error(message);
|
||||
error.isJoi = true;
|
||||
error.name = 'ValidationError';
|
||||
error.details = details;
|
||||
error._object = object;
|
||||
error.annotate = internals.annotate;
|
||||
return error;
|
||||
};
|
||||
|
||||
|
||||
// Inspired by json-stringify-safe
|
||||
|
||||
internals.safeStringify = function (obj, spaces) {
|
||||
|
||||
return JSON.stringify(obj, internals.serializer(), spaces);
|
||||
};
|
||||
|
||||
|
||||
internals.serializer = function () {
|
||||
|
||||
const keys = [];
|
||||
const stack = [];
|
||||
|
||||
const cycleReplacer = (key, value) => {
|
||||
|
||||
if (stack[0] === value) {
|
||||
return '[Circular ~]';
|
||||
}
|
||||
|
||||
return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']';
|
||||
};
|
||||
|
||||
return function (key, value) {
|
||||
|
||||
if (stack.length > 0) {
|
||||
const thisPos = stack.indexOf(this);
|
||||
if (~thisPos) {
|
||||
stack.length = thisPos + 1;
|
||||
keys.length = thisPos + 1;
|
||||
keys[thisPos] = key;
|
||||
}
|
||||
else {
|
||||
stack.push(this);
|
||||
keys.push(key);
|
||||
}
|
||||
|
||||
if (~stack.indexOf(value)) {
|
||||
value = cycleReplacer.call(this, key, value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
stack.push(value);
|
||||
}
|
||||
|
||||
if (value) {
|
||||
const annotations = value[internals.annotations];
|
||||
if (annotations) {
|
||||
if (Array.isArray(value)) {
|
||||
const annotated = [];
|
||||
|
||||
for (let i = 0; i < value.length; ++i) {
|
||||
if (annotations.errors[i]) {
|
||||
annotated.push(`_$idx$_${annotations.errors[i].sort().join(', ')}_$end$_`);
|
||||
}
|
||||
|
||||
annotated.push(value[i]);
|
||||
}
|
||||
|
||||
value = annotated;
|
||||
}
|
||||
else {
|
||||
const errorKeys = Object.keys(annotations.errors);
|
||||
for (let i = 0; i < errorKeys.length; ++i) {
|
||||
const errorKey = errorKeys[i];
|
||||
value[`${errorKey}_$key$_${annotations.errors[errorKey].sort().join(', ')}_$end$_`] = value[errorKey];
|
||||
value[errorKey] = undefined;
|
||||
}
|
||||
|
||||
const missingKeys = Object.keys(annotations.missing);
|
||||
for (let i = 0; i < missingKeys.length; ++i) {
|
||||
const missingKey = missingKeys[i];
|
||||
value[`_$miss$_${missingKey}|${annotations.missing[missingKey]}_$end$_`] = '__missing__';
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
if (value === Infinity || value === -Infinity || Number.isNaN(value) ||
|
||||
typeof value === 'function' || typeof value === 'symbol') {
|
||||
return '[' + value.toString() + ']';
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
internals.annotate = function (stripColorCodes) {
|
||||
|
||||
const redFgEscape = stripColorCodes ? '' : '\u001b[31m';
|
||||
const redBgEscape = stripColorCodes ? '' : '\u001b[41m';
|
||||
const endColor = stripColorCodes ? '' : '\u001b[0m';
|
||||
|
||||
if (typeof this._object !== 'object') {
|
||||
return this.details[0].message;
|
||||
}
|
||||
|
||||
const obj = Hoek.clone(this._object || {});
|
||||
|
||||
for (let i = this.details.length - 1; i >= 0; --i) { // Reverse order to process deepest child first
|
||||
const pos = i + 1;
|
||||
const error = this.details[i];
|
||||
const path = error.path;
|
||||
let ref = obj;
|
||||
for (let j = 0; ; ++j) {
|
||||
const seg = path[j];
|
||||
|
||||
if (ref.isImmutable) {
|
||||
ref = ref.clone(); // joi schemas are not cloned by hoek, we have to take this extra step
|
||||
}
|
||||
|
||||
if (j + 1 < path.length &&
|
||||
ref[seg] &&
|
||||
typeof ref[seg] !== 'string') {
|
||||
|
||||
ref = ref[seg];
|
||||
}
|
||||
else {
|
||||
const refAnnotations = ref[internals.annotations] = ref[internals.annotations] || { errors: {}, missing: {} };
|
||||
const value = ref[seg];
|
||||
const cacheKey = seg || error.context.label;
|
||||
|
||||
if (value !== undefined) {
|
||||
refAnnotations.errors[cacheKey] = refAnnotations.errors[cacheKey] || [];
|
||||
refAnnotations.errors[cacheKey].push(pos);
|
||||
}
|
||||
else {
|
||||
refAnnotations.missing[cacheKey] = pos;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const replacers = {
|
||||
key: /_\$key\$_([, \d]+)_\$end\$_"/g,
|
||||
missing: /"_\$miss\$_([^|]+)\|(\d+)_\$end\$_": "__missing__"/g,
|
||||
arrayIndex: /\s*"_\$idx\$_([, \d]+)_\$end\$_",?\n(.*)/g,
|
||||
specials: /"\[(NaN|Symbol.*|-?Infinity|function.*|\(.*)]"/g
|
||||
};
|
||||
|
||||
let message = internals.safeStringify(obj, 2)
|
||||
.replace(replacers.key, ($0, $1) => `" ${redFgEscape}[${$1}]${endColor}`)
|
||||
.replace(replacers.missing, ($0, $1, $2) => `${redBgEscape}"${$1}"${endColor}${redFgEscape} [${$2}]: -- missing --${endColor}`)
|
||||
.replace(replacers.arrayIndex, ($0, $1, $2) => `\n${$2} ${redFgEscape}[${$1}]${endColor}`)
|
||||
.replace(replacers.specials, ($0, $1) => $1);
|
||||
|
||||
message = `${message}\n${redFgEscape}`;
|
||||
|
||||
for (let i = 0; i < this.details.length; ++i) {
|
||||
const pos = i + 1;
|
||||
message = `${message}\n[${pos}] ${this.details[i].message}`;
|
||||
}
|
||||
|
||||
message = message + endColor;
|
||||
|
||||
return message;
|
||||
};
|
478
web/node_modules/@hapi/joi/lib/index.js
generated
vendored
Executable file
478
web/node_modules/@hapi/joi/lib/index.js
generated
vendored
Executable file
|
@ -0,0 +1,478 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Any = require('./types/any');
|
||||
const Cast = require('./cast');
|
||||
const Errors = require('./errors');
|
||||
const Lazy = require('./types/lazy');
|
||||
const Ref = require('./ref');
|
||||
|
||||
|
||||
const internals = {
|
||||
alternatives: require('./types/alternatives'),
|
||||
array: require('./types/array'),
|
||||
boolean: require('./types/boolean'),
|
||||
binary: require('./types/binary'),
|
||||
date: require('./types/date'),
|
||||
func: require('./types/func'),
|
||||
number: require('./types/number'),
|
||||
object: require('./types/object'),
|
||||
string: require('./types/string'),
|
||||
symbol: require('./types/symbol')
|
||||
};
|
||||
|
||||
|
||||
internals.callWithDefaults = function (schema, args) {
|
||||
|
||||
Hoek.assert(this, 'Must be invoked on a Joi instance.');
|
||||
|
||||
if (this._defaults) {
|
||||
schema = this._defaults(schema);
|
||||
}
|
||||
|
||||
schema._currentJoi = this;
|
||||
|
||||
return schema._init(...args);
|
||||
};
|
||||
|
||||
|
||||
internals.root = function () {
|
||||
|
||||
const any = new Any();
|
||||
|
||||
const root = any.clone();
|
||||
Any.prototype._currentJoi = root;
|
||||
root._currentJoi = root;
|
||||
root._binds = new Set(['any', 'alternatives', 'alt', 'array', 'bool', 'boolean', 'binary', 'date', 'func', 'number', 'object', 'string', 'symbol', 'validate', 'describe', 'compile', 'assert', 'attempt', 'lazy', 'defaults', 'extend', 'allow', 'valid', 'only', 'equal', 'invalid', 'disallow', 'not', 'required', 'exist', 'optional', 'forbidden', 'strip', 'when', 'empty', 'default']);
|
||||
|
||||
root.any = function (...args) {
|
||||
|
||||
Hoek.assert(args.length === 0, 'Joi.any() does not allow arguments.');
|
||||
|
||||
return internals.callWithDefaults.call(this, any, args);
|
||||
};
|
||||
|
||||
root.alternatives = root.alt = function (...args) {
|
||||
|
||||
return internals.callWithDefaults.call(this, internals.alternatives, args);
|
||||
};
|
||||
|
||||
root.array = function (...args) {
|
||||
|
||||
Hoek.assert(args.length === 0, 'Joi.array() does not allow arguments.');
|
||||
|
||||
return internals.callWithDefaults.call(this, internals.array, args);
|
||||
};
|
||||
|
||||
root.boolean = root.bool = function (...args) {
|
||||
|
||||
Hoek.assert(args.length === 0, 'Joi.boolean() does not allow arguments.');
|
||||
|
||||
return internals.callWithDefaults.call(this, internals.boolean, args);
|
||||
};
|
||||
|
||||
root.binary = function (...args) {
|
||||
|
||||
Hoek.assert(args.length === 0, 'Joi.binary() does not allow arguments.');
|
||||
|
||||
return internals.callWithDefaults.call(this, internals.binary, args);
|
||||
};
|
||||
|
||||
root.date = function (...args) {
|
||||
|
||||
Hoek.assert(args.length === 0, 'Joi.date() does not allow arguments.');
|
||||
|
||||
return internals.callWithDefaults.call(this, internals.date, args);
|
||||
};
|
||||
|
||||
root.func = function (...args) {
|
||||
|
||||
Hoek.assert(args.length === 0, 'Joi.func() does not allow arguments.');
|
||||
|
||||
return internals.callWithDefaults.call(this, internals.func, args);
|
||||
};
|
||||
|
||||
root.number = function (...args) {
|
||||
|
||||
Hoek.assert(args.length === 0, 'Joi.number() does not allow arguments.');
|
||||
|
||||
return internals.callWithDefaults.call(this, internals.number, args);
|
||||
};
|
||||
|
||||
root.object = function (...args) {
|
||||
|
||||
return internals.callWithDefaults.call(this, internals.object, args);
|
||||
};
|
||||
|
||||
root.string = function (...args) {
|
||||
|
||||
Hoek.assert(args.length === 0, 'Joi.string() does not allow arguments.');
|
||||
|
||||
return internals.callWithDefaults.call(this, internals.string, args);
|
||||
};
|
||||
|
||||
root.symbol = function (...args) {
|
||||
|
||||
Hoek.assert(args.length === 0, 'Joi.symbol() does not allow arguments.');
|
||||
|
||||
return internals.callWithDefaults.call(this, internals.symbol, args);
|
||||
};
|
||||
|
||||
root.ref = function (...args) {
|
||||
|
||||
return Ref.create(...args);
|
||||
};
|
||||
|
||||
root.isRef = function (ref) {
|
||||
|
||||
return Ref.isRef(ref);
|
||||
};
|
||||
|
||||
root.validate = function (value, ...args /*, [schema], [options], callback */) {
|
||||
|
||||
const last = args[args.length - 1];
|
||||
const callback = typeof last === 'function' ? last : null;
|
||||
|
||||
const count = args.length - (callback ? 1 : 0);
|
||||
if (count === 0) {
|
||||
return any.validate(value, callback);
|
||||
}
|
||||
|
||||
const options = count === 2 ? args[1] : undefined;
|
||||
const schema = this.compile(args[0]);
|
||||
|
||||
return schema._validateWithOptions(value, options, callback);
|
||||
};
|
||||
|
||||
root.describe = function (...args) {
|
||||
|
||||
const schema = args.length ? this.compile(args[0]) : any;
|
||||
return schema.describe();
|
||||
};
|
||||
|
||||
root.compile = function (schema) {
|
||||
|
||||
try {
|
||||
return Cast.schema(this, schema);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.hasOwnProperty('path')) {
|
||||
err.message = err.message + '(' + err.path + ')';
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
root.assert = function (value, schema, message) {
|
||||
|
||||
this.attempt(value, schema, message);
|
||||
};
|
||||
|
||||
root.attempt = function (value, schema, message) {
|
||||
|
||||
const result = this.validate(value, schema);
|
||||
const error = result.error;
|
||||
if (error) {
|
||||
if (!message) {
|
||||
if (typeof error.annotate === 'function') {
|
||||
error.message = error.annotate();
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (!(message instanceof Error)) {
|
||||
if (typeof error.annotate === 'function') {
|
||||
error.message = `${message} ${error.annotate()}`;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw message;
|
||||
}
|
||||
|
||||
return result.value;
|
||||
};
|
||||
|
||||
root.reach = function (schema, path) {
|
||||
|
||||
Hoek.assert(schema && schema instanceof Any, 'you must provide a joi schema');
|
||||
Hoek.assert(Array.isArray(path) || typeof path === 'string', 'path must be a string or an array of strings');
|
||||
|
||||
const reach = (sourceSchema, schemaPath) => {
|
||||
|
||||
if (!schemaPath.length) {
|
||||
return sourceSchema;
|
||||
}
|
||||
|
||||
const children = sourceSchema._inner.children;
|
||||
if (!children) {
|
||||
return;
|
||||
}
|
||||
|
||||
const key = schemaPath.shift();
|
||||
for (let i = 0; i < children.length; ++i) {
|
||||
const child = children[i];
|
||||
if (child.key === key) {
|
||||
return reach(child.schema, schemaPath);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const schemaPath = typeof path === 'string' ? (path ? path.split('.') : []) : path.slice();
|
||||
|
||||
return reach(schema, schemaPath);
|
||||
};
|
||||
|
||||
root.lazy = function (...args) {
|
||||
|
||||
return internals.callWithDefaults.call(this, Lazy, args);
|
||||
};
|
||||
|
||||
root.defaults = function (fn) {
|
||||
|
||||
Hoek.assert(typeof fn === 'function', 'Defaults must be a function');
|
||||
|
||||
let joi = Object.create(this.any());
|
||||
joi = fn(joi);
|
||||
|
||||
Hoek.assert(joi && joi instanceof this.constructor, 'defaults() must return a schema');
|
||||
|
||||
Object.assign(joi, this, joi.clone()); // Re-add the types from `this` but also keep the settings from joi's potential new defaults
|
||||
|
||||
joi._defaults = (schema) => {
|
||||
|
||||
if (this._defaults) {
|
||||
schema = this._defaults(schema);
|
||||
Hoek.assert(schema instanceof this.constructor, 'defaults() must return a schema');
|
||||
}
|
||||
|
||||
schema = fn(schema);
|
||||
Hoek.assert(schema instanceof this.constructor, 'defaults() must return a schema');
|
||||
return schema;
|
||||
};
|
||||
|
||||
return joi;
|
||||
};
|
||||
|
||||
root.bind = function () {
|
||||
|
||||
const joi = Object.create(this);
|
||||
|
||||
joi._binds.forEach((bind) => {
|
||||
|
||||
joi[bind] = joi[bind].bind(joi);
|
||||
});
|
||||
|
||||
return joi;
|
||||
};
|
||||
|
||||
root.extend = function (...args) {
|
||||
|
||||
const extensions = Hoek.flatten(args);
|
||||
Hoek.assert(extensions.length > 0, 'You need to provide at least one extension');
|
||||
|
||||
this.assert(extensions, root.extensionsSchema);
|
||||
|
||||
const joi = Object.create(this.any());
|
||||
Object.assign(joi, this);
|
||||
joi._currentJoi = joi;
|
||||
joi._binds = new Set(joi._binds);
|
||||
|
||||
for (let i = 0; i < extensions.length; ++i) {
|
||||
let extension = extensions[i];
|
||||
|
||||
if (typeof extension === 'function') {
|
||||
extension = extension(joi);
|
||||
}
|
||||
|
||||
this.assert(extension, root.extensionSchema);
|
||||
|
||||
const base = (extension.base || this.any()).clone(); // Cloning because we're going to override language afterwards
|
||||
const ctor = base.constructor;
|
||||
const type = class extends ctor { // eslint-disable-line no-loop-func
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
if (extension.base) {
|
||||
Object.assign(this, base);
|
||||
}
|
||||
|
||||
this._type = extension.name;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
if (extension.language) {
|
||||
const lang = {
|
||||
[extension.name]: extension.language
|
||||
};
|
||||
type.prototype._language = Hoek.applyToDefaults(type.prototype._language || (base._settings && base._settings.language) || {}, lang);
|
||||
}
|
||||
|
||||
|
||||
if (extension.coerce) {
|
||||
type.prototype._coerce = function (value, state, options) {
|
||||
|
||||
if (ctor.prototype._coerce) {
|
||||
const baseRet = ctor.prototype._coerce.call(this, value, state, options);
|
||||
|
||||
if (baseRet.errors) {
|
||||
return baseRet;
|
||||
}
|
||||
|
||||
value = baseRet.value;
|
||||
}
|
||||
|
||||
const ret = extension.coerce.call(this, value, state, options);
|
||||
if (ret instanceof Errors.Err) {
|
||||
return { value, errors: ret };
|
||||
}
|
||||
|
||||
return { value: ret };
|
||||
};
|
||||
}
|
||||
|
||||
if (extension.pre) {
|
||||
type.prototype._base = function (value, state, options) {
|
||||
|
||||
if (ctor.prototype._base) {
|
||||
const baseRet = ctor.prototype._base.call(this, value, state, options);
|
||||
|
||||
if (baseRet.errors) {
|
||||
return baseRet;
|
||||
}
|
||||
|
||||
value = baseRet.value;
|
||||
}
|
||||
|
||||
const ret = extension.pre.call(this, value, state, options);
|
||||
if (ret instanceof Errors.Err) {
|
||||
return { value, errors: ret };
|
||||
}
|
||||
|
||||
return { value: ret };
|
||||
};
|
||||
}
|
||||
|
||||
if (extension.rules) {
|
||||
for (let j = 0; j < extension.rules.length; ++j) {
|
||||
const rule = extension.rules[j];
|
||||
const ruleArgs = rule.params ?
|
||||
(rule.params instanceof Any ? rule.params._inner.children.map((k) => k.key) : Object.keys(rule.params)) :
|
||||
[];
|
||||
const validateArgs = rule.params ? Cast.schema(this, rule.params) : null;
|
||||
|
||||
type.prototype[rule.name] = function (...rArgs) { // eslint-disable-line no-loop-func
|
||||
|
||||
if (rArgs.length > ruleArgs.length) {
|
||||
throw new Error('Unexpected number of arguments');
|
||||
}
|
||||
|
||||
let hasRef = false;
|
||||
let arg = {};
|
||||
|
||||
for (let k = 0; k < ruleArgs.length; ++k) {
|
||||
arg[ruleArgs[k]] = rArgs[k];
|
||||
if (!hasRef && Ref.isRef(rArgs[k])) {
|
||||
hasRef = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (validateArgs) {
|
||||
arg = joi.attempt(arg, validateArgs);
|
||||
}
|
||||
|
||||
let schema;
|
||||
if (rule.validate && !rule.setup) {
|
||||
const validate = function (value, state, options) {
|
||||
|
||||
return rule.validate.call(this, arg, value, state, options);
|
||||
};
|
||||
|
||||
schema = this._test(rule.name, arg, validate, {
|
||||
description: rule.description,
|
||||
hasRef
|
||||
});
|
||||
}
|
||||
else {
|
||||
schema = this.clone();
|
||||
}
|
||||
|
||||
if (rule.setup) {
|
||||
const newSchema = rule.setup.call(schema, arg);
|
||||
if (newSchema !== undefined) {
|
||||
Hoek.assert(newSchema instanceof Any, `Setup of extension Joi.${this._type}().${rule.name}() must return undefined or a Joi object`);
|
||||
schema = newSchema;
|
||||
}
|
||||
|
||||
if (rule.validate) {
|
||||
const validate = function (value, state, options) {
|
||||
|
||||
return rule.validate.call(this, arg, value, state, options);
|
||||
};
|
||||
|
||||
schema = schema._test(rule.name, arg, validate, {
|
||||
description: rule.description,
|
||||
hasRef
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return schema;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (extension.describe) {
|
||||
type.prototype.describe = function () {
|
||||
|
||||
const description = ctor.prototype.describe.call(this);
|
||||
return extension.describe.call(this, description);
|
||||
};
|
||||
}
|
||||
|
||||
const instance = new type();
|
||||
joi[extension.name] = function (...extArgs) {
|
||||
|
||||
return internals.callWithDefaults.call(this, instance, extArgs);
|
||||
};
|
||||
|
||||
joi._binds.add(extension.name);
|
||||
}
|
||||
|
||||
return joi;
|
||||
};
|
||||
|
||||
root.extensionSchema = internals.object.keys({
|
||||
base: internals.object.type(Any, 'Joi object'),
|
||||
name: internals.string.required(),
|
||||
coerce: internals.func.arity(3),
|
||||
pre: internals.func.arity(3),
|
||||
language: internals.object,
|
||||
describe: internals.func.arity(1),
|
||||
rules: internals.array.items(internals.object.keys({
|
||||
name: internals.string.required(),
|
||||
setup: internals.func.arity(1),
|
||||
validate: internals.func.arity(4),
|
||||
params: [
|
||||
internals.object.pattern(/.*/, internals.object.type(Any, 'Joi object')),
|
||||
internals.object.type(internals.object.constructor, 'Joi object')
|
||||
],
|
||||
description: [internals.string, internals.func.arity(1)]
|
||||
}).or('setup', 'validate'))
|
||||
}).strict();
|
||||
|
||||
root.extensionsSchema = internals.array.items([internals.object, internals.func.arity(1)]).strict();
|
||||
|
||||
root.version = require('../package.json').version;
|
||||
|
||||
return root;
|
||||
};
|
||||
|
||||
|
||||
module.exports = internals.root();
|
161
web/node_modules/@hapi/joi/lib/language.js
generated
vendored
Executable file
161
web/node_modules/@hapi/joi/lib/language.js
generated
vendored
Executable file
|
@ -0,0 +1,161 @@
|
|||
'use strict';
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
exports.errors = {
|
||||
root: 'value',
|
||||
key: '"{{!label}}" ',
|
||||
messages: {
|
||||
wrapArrays: true
|
||||
},
|
||||
any: {
|
||||
unknown: 'is not allowed',
|
||||
invalid: 'contains an invalid value',
|
||||
empty: 'is not allowed to be empty',
|
||||
required: 'is required',
|
||||
allowOnly: 'must be one of {{valids}}',
|
||||
default: 'threw an error when running default method'
|
||||
},
|
||||
alternatives: {
|
||||
base: 'not matching any of the allowed alternatives',
|
||||
child: null
|
||||
},
|
||||
array: {
|
||||
base: 'must be an array',
|
||||
includes: 'at position {{pos}} does not match any of the allowed types',
|
||||
includesSingle: 'single value of "{{!label}}" does not match any of the allowed types',
|
||||
includesOne: 'at position {{pos}} fails because {{reason}}',
|
||||
includesOneSingle: 'single value of "{{!label}}" fails because {{reason}}',
|
||||
includesRequiredUnknowns: 'does not contain {{unknownMisses}} required value(s)',
|
||||
includesRequiredKnowns: 'does not contain {{knownMisses}}',
|
||||
includesRequiredBoth: 'does not contain {{knownMisses}} and {{unknownMisses}} other required value(s)',
|
||||
excludes: 'at position {{pos}} contains an excluded value',
|
||||
excludesSingle: 'single value of "{{!label}}" contains an excluded value',
|
||||
hasKnown: 'does not contain at least one required match for type "{{!patternLabel}}"',
|
||||
hasUnknown: 'does not contain at least one required match',
|
||||
min: 'must contain at least {{limit}} items',
|
||||
max: 'must contain less than or equal to {{limit}} items',
|
||||
length: 'must contain {{limit}} items',
|
||||
ordered: 'at position {{pos}} fails because {{reason}}',
|
||||
orderedLength: 'at position {{pos}} fails because array must contain at most {{limit}} items',
|
||||
ref: 'references "{{ref}}" which is not a positive integer',
|
||||
sparse: 'must not be a sparse array',
|
||||
unique: 'position {{pos}} contains a duplicate value'
|
||||
},
|
||||
boolean: {
|
||||
base: 'must be a boolean'
|
||||
},
|
||||
binary: {
|
||||
base: 'must be a buffer or a string',
|
||||
min: 'must be at least {{limit}} bytes',
|
||||
max: 'must be less than or equal to {{limit}} bytes',
|
||||
length: 'must be {{limit}} bytes'
|
||||
},
|
||||
date: {
|
||||
base: 'must be a number of milliseconds or valid date string',
|
||||
strict: 'must be a valid date',
|
||||
min: 'must be larger than or equal to "{{limit}}"',
|
||||
max: 'must be less than or equal to "{{limit}}"',
|
||||
less: 'must be less than "{{limit}}"',
|
||||
greater: 'must be greater than "{{limit}}"',
|
||||
isoDate: 'must be a valid ISO 8601 date',
|
||||
timestamp: {
|
||||
javascript: 'must be a valid timestamp or number of milliseconds',
|
||||
unix: 'must be a valid timestamp or number of seconds'
|
||||
},
|
||||
ref: 'references "{{ref}}" which is not a date'
|
||||
},
|
||||
function: {
|
||||
base: 'must be a Function',
|
||||
arity: 'must have an arity of {{n}}',
|
||||
minArity: 'must have an arity greater or equal to {{n}}',
|
||||
maxArity: 'must have an arity lesser or equal to {{n}}',
|
||||
ref: 'must be a Joi reference',
|
||||
class: 'must be a class'
|
||||
},
|
||||
lazy: {
|
||||
base: '!!schema error: lazy schema must be set',
|
||||
schema: '!!schema error: lazy schema function must return a schema'
|
||||
},
|
||||
object: {
|
||||
base: 'must be an object',
|
||||
child: '!!child "{{!child}}" fails because {{reason}}',
|
||||
min: 'must have at least {{limit}} children',
|
||||
max: 'must have less than or equal to {{limit}} children',
|
||||
length: 'must have {{limit}} children',
|
||||
allowUnknown: '!!"{{!child}}" is not allowed',
|
||||
with: '!!"{{mainWithLabel}}" missing required peer "{{peerWithLabel}}"',
|
||||
without: '!!"{{mainWithLabel}}" conflict with forbidden peer "{{peerWithLabel}}"',
|
||||
missing: 'must contain at least one of {{peersWithLabels}}',
|
||||
xor: 'contains a conflict between exclusive peers {{peersWithLabels}}',
|
||||
oxor: 'contains a conflict between optional exclusive peers {{peersWithLabels}}',
|
||||
and: 'contains {{presentWithLabels}} without its required peers {{missingWithLabels}}',
|
||||
nand: '!!"{{mainWithLabel}}" must not exist simultaneously with {{peersWithLabels}}',
|
||||
assert: '!!"{{ref}}" validation failed because "{{ref}}" failed to {{message}}',
|
||||
rename: {
|
||||
multiple: 'cannot rename child "{{from}}" because multiple renames are disabled and another key was already renamed to "{{to}}"',
|
||||
override: 'cannot rename child "{{from}}" because override is disabled and target "{{to}}" exists',
|
||||
regex: {
|
||||
multiple: 'cannot rename children {{from}} because multiple renames are disabled and another key was already renamed to "{{to}}"',
|
||||
override: 'cannot rename children {{from}} because override is disabled and target "{{to}}" exists'
|
||||
}
|
||||
},
|
||||
type: 'must be an instance of "{{type}}"',
|
||||
schema: 'must be a Joi instance'
|
||||
},
|
||||
number: {
|
||||
base: 'must be a number',
|
||||
unsafe: 'must be a safe number',
|
||||
min: 'must be larger than or equal to {{limit}}',
|
||||
max: 'must be less than or equal to {{limit}}',
|
||||
less: 'must be less than {{limit}}',
|
||||
greater: 'must be greater than {{limit}}',
|
||||
integer: 'must be an integer',
|
||||
negative: 'must be a negative number',
|
||||
positive: 'must be a positive number',
|
||||
precision: 'must have no more than {{limit}} decimal places',
|
||||
ref: 'references "{{ref}}" which is not a number',
|
||||
multiple: 'must be a multiple of {{multiple}}',
|
||||
port: 'must be a valid port'
|
||||
},
|
||||
string: {
|
||||
base: 'must be a string',
|
||||
min: 'length must be at least {{limit}} characters long',
|
||||
max: 'length must be less than or equal to {{limit}} characters long',
|
||||
length: 'length must be {{limit}} characters long',
|
||||
alphanum: 'must only contain alpha-numeric characters',
|
||||
token: 'must only contain alpha-numeric and underscore characters',
|
||||
regex: {
|
||||
base: 'with value "{{!value}}" fails to match the required pattern: {{pattern}}',
|
||||
name: 'with value "{{!value}}" fails to match the {{name}} pattern',
|
||||
invert: {
|
||||
base: 'with value "{{!value}}" matches the inverted pattern: {{pattern}}',
|
||||
name: 'with value "{{!value}}" matches the inverted {{name}} pattern'
|
||||
}
|
||||
},
|
||||
email: 'must be a valid email',
|
||||
uri: 'must be a valid uri',
|
||||
uriRelativeOnly: 'must be a valid relative uri',
|
||||
uriCustomScheme: 'must be a valid uri with a scheme matching the {{scheme}} pattern',
|
||||
isoDate: 'must be a valid ISO 8601 date',
|
||||
guid: 'must be a valid GUID',
|
||||
hex: 'must only contain hexadecimal characters',
|
||||
hexAlign: 'hex decoded representation must be byte aligned',
|
||||
base64: 'must be a valid base64 string',
|
||||
dataUri: 'must be a valid dataUri string',
|
||||
hostname: 'must be a valid hostname',
|
||||
normalize: 'must be unicode normalized in the {{form}} form',
|
||||
lowercase: 'must only contain lowercase characters',
|
||||
uppercase: 'must only contain uppercase characters',
|
||||
trim: 'must not have leading or trailing whitespace',
|
||||
creditCard: 'must be a credit card',
|
||||
ref: 'references "{{ref}}" which is not a number',
|
||||
ip: 'must be a valid ip address with a {{cidr}} CIDR',
|
||||
ipVersion: 'must be a valid ip address of one of the following versions {{version}} with a {{cidr}} CIDR'
|
||||
},
|
||||
symbol: {
|
||||
base: 'must be a symbol',
|
||||
map: 'must be one of {{map}}'
|
||||
}
|
||||
};
|
49
web/node_modules/@hapi/joi/lib/ref.js
generated
vendored
Executable file
49
web/node_modules/@hapi/joi/lib/ref.js
generated
vendored
Executable file
|
@ -0,0 +1,49 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
exports.create = function (key, options) {
|
||||
|
||||
Hoek.assert(typeof key === 'string', 'Invalid reference key:', key);
|
||||
|
||||
const settings = Hoek.clone(options); // options can be reused and modified
|
||||
|
||||
const ref = function (value, validationOptions) {
|
||||
|
||||
return Hoek.reach(ref.isContext ? validationOptions.context : value, ref.key, settings);
|
||||
};
|
||||
|
||||
ref.isContext = (key[0] === ((settings && settings.contextPrefix) || '$'));
|
||||
ref.key = (ref.isContext ? key.slice(1) : key);
|
||||
ref.path = ref.key.split((settings && settings.separator) || '.');
|
||||
ref.depth = ref.path.length;
|
||||
ref.root = ref.path[0];
|
||||
ref.isJoi = true;
|
||||
|
||||
ref.toString = function () {
|
||||
|
||||
return (ref.isContext ? 'context:' : 'ref:') + ref.key;
|
||||
};
|
||||
|
||||
return ref;
|
||||
};
|
||||
|
||||
|
||||
exports.isRef = function (ref) {
|
||||
|
||||
return typeof ref === 'function' && ref.isJoi;
|
||||
};
|
||||
|
||||
|
||||
exports.push = function (array, ref) {
|
||||
|
||||
if (exports.isRef(ref) &&
|
||||
!ref.isContext) {
|
||||
|
||||
array.push(ref.root);
|
||||
}
|
||||
};
|
20
web/node_modules/@hapi/joi/lib/schemas.js
generated
vendored
Executable file
20
web/node_modules/@hapi/joi/lib/schemas.js
generated
vendored
Executable file
|
@ -0,0 +1,20 @@
|
|||
'use strict';
|
||||
|
||||
const Joi = require('./index');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
exports.options = Joi.object({
|
||||
abortEarly: Joi.boolean(),
|
||||
convert: Joi.boolean(),
|
||||
allowUnknown: Joi.boolean(),
|
||||
skipFunctions: Joi.boolean(),
|
||||
stripUnknown: [Joi.boolean(), Joi.object({ arrays: Joi.boolean(), objects: Joi.boolean() }).or('arrays', 'objects')],
|
||||
language: Joi.object(),
|
||||
presence: Joi.string().only('required', 'optional', 'forbidden', 'ignore'),
|
||||
context: Joi.object(),
|
||||
noDefaults: Joi.boolean(),
|
||||
escapeHtml: Joi.boolean()
|
||||
}).strict();
|
191
web/node_modules/@hapi/joi/lib/set.js
generated
vendored
Normal file
191
web/node_modules/@hapi/joi/lib/set.js
generated
vendored
Normal file
|
@ -0,0 +1,191 @@
|
|||
'use strict';
|
||||
|
||||
const Ref = require('./ref');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
internals.extendedCheckForValue = function (value, insensitive) {
|
||||
|
||||
const valueType = typeof value;
|
||||
|
||||
if (valueType === 'object') {
|
||||
if (value instanceof Date) {
|
||||
return (item) => {
|
||||
|
||||
return item instanceof Date && value.getTime() === item.getTime();
|
||||
};
|
||||
}
|
||||
|
||||
if (Buffer.isBuffer(value)) {
|
||||
return (item) => {
|
||||
|
||||
return Buffer.isBuffer(item) && value.length === item.length && value.toString('binary') === item.toString('binary');
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (insensitive && valueType === 'string') {
|
||||
const lowercaseValue = value.toLowerCase();
|
||||
return (item) => {
|
||||
|
||||
return typeof item === 'string' && lowercaseValue === item.toLowerCase();
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
module.exports = class InternalSet {
|
||||
|
||||
constructor(from) {
|
||||
|
||||
this._set = new Set(from);
|
||||
this._hasRef = false;
|
||||
}
|
||||
|
||||
add(value, refs) {
|
||||
|
||||
const isRef = Ref.isRef(value);
|
||||
if (!isRef && this.has(value, null, null, false)) {
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
if (refs !== undefined) { // If it's a merge, we don't have any refs
|
||||
Ref.push(refs, value);
|
||||
}
|
||||
|
||||
this._set.add(value);
|
||||
|
||||
this._hasRef |= isRef;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
merge(add, remove) {
|
||||
|
||||
for (const item of add._set) {
|
||||
this.add(item);
|
||||
}
|
||||
|
||||
for (const item of remove._set) {
|
||||
this.remove(item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
remove(value) {
|
||||
|
||||
this._set.delete(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
has(value, state, options, insensitive) {
|
||||
|
||||
return !!this.get(value, state, options, insensitive);
|
||||
}
|
||||
|
||||
get(value, state, options, insensitive) {
|
||||
|
||||
if (!this._set.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const hasValue = this._set.has(value);
|
||||
if (hasValue) {
|
||||
return { value };
|
||||
}
|
||||
|
||||
const extendedCheck = internals.extendedCheckForValue(value, insensitive);
|
||||
if (!extendedCheck) {
|
||||
if (state && this._hasRef) {
|
||||
for (let item of this._set) {
|
||||
if (Ref.isRef(item)) {
|
||||
item = [].concat(item(state.reference || state.parent, options));
|
||||
const found = item.indexOf(value);
|
||||
if (found >= 0) {
|
||||
return { value: item[found] };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return this._has(value, state, options, extendedCheck);
|
||||
}
|
||||
|
||||
_has(value, state, options, check) {
|
||||
|
||||
const checkRef = !!(state && this._hasRef);
|
||||
|
||||
const isReallyEqual = function (item) {
|
||||
|
||||
if (value === item) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return check(item);
|
||||
};
|
||||
|
||||
for (let item of this._set) {
|
||||
if (checkRef && Ref.isRef(item)) { // Only resolve references if there is a state, otherwise it's a merge
|
||||
item = item(state.reference || state.parent, options);
|
||||
|
||||
if (Array.isArray(item)) {
|
||||
const found = item.findIndex(isReallyEqual);
|
||||
if (found >= 0) {
|
||||
return {
|
||||
value: item[found]
|
||||
};
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isReallyEqual(item)) {
|
||||
return {
|
||||
value: item
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
values(options) {
|
||||
|
||||
if (options && options.stripUndefined) {
|
||||
const values = [];
|
||||
|
||||
for (const item of this._set) {
|
||||
if (item !== undefined) {
|
||||
values.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
return Array.from(this._set);
|
||||
}
|
||||
|
||||
slice() {
|
||||
|
||||
const set = new InternalSet(this._set);
|
||||
set._hasRef = this._hasRef;
|
||||
return set;
|
||||
}
|
||||
|
||||
concat(source) {
|
||||
|
||||
const set = new InternalSet([...this._set, ...source._set]);
|
||||
set._hasRef = !!(this._hasRef | source._hasRef);
|
||||
return set;
|
||||
}
|
||||
};
|
215
web/node_modules/@hapi/joi/lib/types/alternatives/index.js
generated
vendored
Executable file
215
web/node_modules/@hapi/joi/lib/types/alternatives/index.js
generated
vendored
Executable file
|
@ -0,0 +1,215 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Any = require('../any');
|
||||
const Cast = require('../../cast');
|
||||
const Ref = require('../../ref');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
internals.Alternatives = class extends Any {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this._type = 'alternatives';
|
||||
this._invalids.remove(null);
|
||||
this._inner.matches = [];
|
||||
}
|
||||
|
||||
_init(...args) {
|
||||
|
||||
return args.length ? this.try(...args) : this;
|
||||
}
|
||||
|
||||
_base(value, state, options) {
|
||||
|
||||
const errors = [];
|
||||
const il = this._inner.matches.length;
|
||||
const baseType = this._baseType;
|
||||
|
||||
for (let i = 0; i < il; ++i) {
|
||||
const item = this._inner.matches[i];
|
||||
if (!item.schema) {
|
||||
const schema = item.peek || item.is;
|
||||
const input = item.is ? item.ref(state.reference || state.parent, options) : value;
|
||||
const failed = schema._validate(input, null, options, state.parent).errors;
|
||||
|
||||
if (failed) {
|
||||
if (item.otherwise) {
|
||||
return item.otherwise._validate(value, state, options);
|
||||
}
|
||||
}
|
||||
else if (item.then) {
|
||||
return item.then._validate(value, state, options);
|
||||
}
|
||||
|
||||
if (i === (il - 1) && baseType) {
|
||||
return baseType._validate(value, state, options);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const result = item.schema._validate(value, state, options);
|
||||
if (!result.errors) { // Found a valid match
|
||||
return result;
|
||||
}
|
||||
|
||||
errors.push(...result.errors);
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
return { errors: this.createError('alternatives.child', { reason: errors }, state, options) };
|
||||
}
|
||||
|
||||
return { errors: this.createError('alternatives.base', null, state, options) };
|
||||
}
|
||||
|
||||
try(...schemas) {
|
||||
|
||||
schemas = Hoek.flatten(schemas);
|
||||
Hoek.assert(schemas.length, 'Cannot add other alternatives without at least one schema');
|
||||
|
||||
const obj = this.clone();
|
||||
|
||||
for (let i = 0; i < schemas.length; ++i) {
|
||||
const cast = Cast.schema(this._currentJoi, schemas[i]);
|
||||
if (cast._refs.length) {
|
||||
obj._refs.push(...cast._refs);
|
||||
}
|
||||
|
||||
obj._inner.matches.push({ schema: cast });
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
when(condition, options) {
|
||||
|
||||
let schemaCondition = false;
|
||||
Hoek.assert(Ref.isRef(condition) || typeof condition === 'string' || (schemaCondition = condition instanceof Any), 'Invalid condition:', condition);
|
||||
Hoek.assert(options, 'Missing options');
|
||||
Hoek.assert(typeof options === 'object', 'Invalid options');
|
||||
if (schemaCondition) {
|
||||
Hoek.assert(!options.hasOwnProperty('is'), '"is" can not be used with a schema condition');
|
||||
}
|
||||
else {
|
||||
Hoek.assert(options.hasOwnProperty('is'), 'Missing "is" directive');
|
||||
}
|
||||
|
||||
Hoek.assert(options.then !== undefined || options.otherwise !== undefined, 'options must have at least one of "then" or "otherwise"');
|
||||
|
||||
const obj = this.clone();
|
||||
let is;
|
||||
if (!schemaCondition) {
|
||||
is = Cast.schema(this._currentJoi, options.is);
|
||||
|
||||
if (options.is === null || !(Ref.isRef(options.is) || options.is instanceof Any)) {
|
||||
|
||||
// Only apply required if this wasn't already a schema or a ref, we'll suppose people know what they're doing
|
||||
is = is.required();
|
||||
}
|
||||
}
|
||||
|
||||
const item = {
|
||||
ref: schemaCondition ? null : Cast.ref(condition),
|
||||
peek: schemaCondition ? condition : null,
|
||||
is,
|
||||
then: options.then !== undefined ? Cast.schema(this._currentJoi, options.then) : undefined,
|
||||
otherwise: options.otherwise !== undefined ? Cast.schema(this._currentJoi, options.otherwise) : undefined
|
||||
};
|
||||
|
||||
if (obj._baseType) {
|
||||
|
||||
item.then = item.then && obj._baseType.concat(item.then);
|
||||
item.otherwise = item.otherwise && obj._baseType.concat(item.otherwise);
|
||||
}
|
||||
|
||||
if (!schemaCondition) {
|
||||
Ref.push(obj._refs, item.ref);
|
||||
obj._refs.push(...item.is._refs);
|
||||
}
|
||||
|
||||
if (item.then && item.then._refs.length) {
|
||||
obj._refs.push(...item.then._refs);
|
||||
}
|
||||
|
||||
if (item.otherwise && item.otherwise._refs.length) {
|
||||
obj._refs.push(...item.otherwise._refs);
|
||||
}
|
||||
|
||||
obj._inner.matches.push(item);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
label(name) {
|
||||
|
||||
const obj = super.label(name);
|
||||
obj._inner.matches = obj._inner.matches.map((match) => {
|
||||
|
||||
if (match.schema) {
|
||||
return { schema: match.schema.label(name) };
|
||||
}
|
||||
|
||||
match = Object.assign({}, match);
|
||||
if (match.then) {
|
||||
match.then = match.then.label(name);
|
||||
}
|
||||
|
||||
if (match.otherwise) {
|
||||
match.otherwise = match.otherwise.label(name);
|
||||
}
|
||||
|
||||
return match;
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
|
||||
describe() {
|
||||
|
||||
const description = super.describe();
|
||||
const alternatives = [];
|
||||
for (let i = 0; i < this._inner.matches.length; ++i) {
|
||||
const item = this._inner.matches[i];
|
||||
if (item.schema) {
|
||||
|
||||
// try()
|
||||
|
||||
alternatives.push(item.schema.describe());
|
||||
}
|
||||
else {
|
||||
|
||||
// when()
|
||||
|
||||
const when = item.is ? {
|
||||
ref: item.ref.toString(),
|
||||
is: item.is.describe()
|
||||
} : {
|
||||
peek: item.peek.describe()
|
||||
};
|
||||
|
||||
if (item.then) {
|
||||
when.then = item.then.describe();
|
||||
}
|
||||
|
||||
if (item.otherwise) {
|
||||
when.otherwise = item.otherwise.describe();
|
||||
}
|
||||
|
||||
alternatives.push(when);
|
||||
}
|
||||
}
|
||||
|
||||
description.alternatives = alternatives;
|
||||
return description;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
module.exports = new internals.Alternatives();
|
984
web/node_modules/@hapi/joi/lib/types/any/index.js
generated
vendored
Executable file
984
web/node_modules/@hapi/joi/lib/types/any/index.js
generated
vendored
Executable file
|
@ -0,0 +1,984 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Cast = require('../../cast');
|
||||
const Settings = require('./settings');
|
||||
const Ref = require('../../ref');
|
||||
const Errors = require('../../errors');
|
||||
const State = require('../state');
|
||||
const Symbols = require('../symbols');
|
||||
|
||||
const Pkg = require('../../../package.json');
|
||||
|
||||
let Alternatives = null; // Delay-loaded to prevent circular dependencies
|
||||
let Schemas = null;
|
||||
|
||||
|
||||
const internals = {
|
||||
Set: require('../../set'),
|
||||
symbol: Symbol.for('@hapi/joi/schema')
|
||||
};
|
||||
|
||||
|
||||
internals.defaults = {
|
||||
abortEarly: true,
|
||||
convert: true,
|
||||
allowUnknown: false,
|
||||
skipFunctions: false,
|
||||
stripUnknown: false,
|
||||
language: {},
|
||||
presence: 'optional',
|
||||
noDefaults: false,
|
||||
escapeHtml: false
|
||||
|
||||
// context: null
|
||||
};
|
||||
|
||||
|
||||
module.exports = internals.Any = class {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.isJoi = true;
|
||||
this._type = 'any';
|
||||
this._settings = null;
|
||||
this._valids = new internals.Set();
|
||||
this._invalids = new internals.Set();
|
||||
this._tests = [];
|
||||
this._refs = [];
|
||||
this._flags = {
|
||||
/*
|
||||
presence: 'optional', // optional, required, forbidden, ignore
|
||||
allowOnly: false,
|
||||
allowUnknown: undefined,
|
||||
default: undefined,
|
||||
forbidden: false,
|
||||
encoding: undefined,
|
||||
insensitive: false,
|
||||
trim: false,
|
||||
normalize: undefined, // NFC, NFD, NFKC, NFKD
|
||||
case: undefined, // upper, lower
|
||||
empty: undefined,
|
||||
func: false,
|
||||
raw: false
|
||||
*/
|
||||
};
|
||||
|
||||
this._description = null;
|
||||
this._unit = null;
|
||||
this._notes = [];
|
||||
this._tags = [];
|
||||
this._examples = [];
|
||||
this._meta = [];
|
||||
|
||||
this._inner = {}; // Hash of arrays of immutable objects
|
||||
}
|
||||
|
||||
_init() {
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
get schemaType() {
|
||||
|
||||
return this._type;
|
||||
}
|
||||
|
||||
createError(type, context, state, options, flags = this._flags) {
|
||||
|
||||
return Errors.create(type, context, state, options, flags);
|
||||
}
|
||||
|
||||
createOverrideError(type, context, state, options, message, template) {
|
||||
|
||||
return Errors.create(type, context, state, options, this._flags, message, template);
|
||||
}
|
||||
|
||||
checkOptions(options) {
|
||||
|
||||
Schemas = Schemas || require('../../schemas');
|
||||
|
||||
const result = Schemas.options.validate(options);
|
||||
|
||||
if (result.error) {
|
||||
throw new Error(result.error.details[0].message);
|
||||
}
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
const obj = Object.create(Object.getPrototypeOf(this));
|
||||
|
||||
obj.isJoi = true;
|
||||
obj._currentJoi = this._currentJoi;
|
||||
obj._type = this._type;
|
||||
obj._settings = this._settings;
|
||||
obj._baseType = this._baseType;
|
||||
obj._valids = this._valids.slice();
|
||||
obj._invalids = this._invalids.slice();
|
||||
obj._tests = this._tests.slice();
|
||||
obj._refs = this._refs.slice();
|
||||
obj._flags = Hoek.clone(this._flags);
|
||||
|
||||
obj._description = this._description;
|
||||
obj._unit = this._unit;
|
||||
obj._notes = this._notes.slice();
|
||||
obj._tags = this._tags.slice();
|
||||
obj._examples = this._examples.slice();
|
||||
obj._meta = this._meta.slice();
|
||||
|
||||
obj._inner = {};
|
||||
const inners = Object.keys(this._inner);
|
||||
for (let i = 0; i < inners.length; ++i) {
|
||||
const key = inners[i];
|
||||
obj._inner[key] = this._inner[key] ? this._inner[key].slice() : null;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
concat(schema) {
|
||||
|
||||
Hoek.assert(schema instanceof internals.Any, 'Invalid schema object');
|
||||
Hoek.assert(this._type === 'any' || schema._type === 'any' || schema._type === this._type, 'Cannot merge type', this._type, 'with another type:', schema._type);
|
||||
|
||||
let obj = this.clone();
|
||||
|
||||
if (this._type === 'any' && schema._type !== 'any') {
|
||||
|
||||
// Reset values as if we were "this"
|
||||
const tmpObj = schema.clone();
|
||||
const keysToRestore = ['_settings', '_valids', '_invalids', '_tests', '_refs', '_flags', '_description', '_unit',
|
||||
'_notes', '_tags', '_examples', '_meta', '_inner'];
|
||||
|
||||
for (let i = 0; i < keysToRestore.length; ++i) {
|
||||
tmpObj[keysToRestore[i]] = obj[keysToRestore[i]];
|
||||
}
|
||||
|
||||
obj = tmpObj;
|
||||
}
|
||||
|
||||
obj._settings = obj._settings ? Settings.concat(obj._settings, schema._settings) : schema._settings;
|
||||
obj._valids.merge(schema._valids, schema._invalids);
|
||||
obj._invalids.merge(schema._invalids, schema._valids);
|
||||
obj._tests.push(...schema._tests);
|
||||
obj._refs.push(...schema._refs);
|
||||
if (obj._flags.empty && schema._flags.empty) {
|
||||
obj._flags.empty = obj._flags.empty.concat(schema._flags.empty);
|
||||
const flags = Object.assign({}, schema._flags);
|
||||
delete flags.empty;
|
||||
Hoek.merge(obj._flags, flags);
|
||||
}
|
||||
else if (schema._flags.empty) {
|
||||
obj._flags.empty = schema._flags.empty;
|
||||
const flags = Object.assign({}, schema._flags);
|
||||
delete flags.empty;
|
||||
Hoek.merge(obj._flags, flags);
|
||||
}
|
||||
else {
|
||||
Hoek.merge(obj._flags, schema._flags);
|
||||
}
|
||||
|
||||
obj._description = schema._description || obj._description;
|
||||
obj._unit = schema._unit || obj._unit;
|
||||
obj._notes.push(...schema._notes);
|
||||
obj._tags.push(...schema._tags);
|
||||
obj._examples.push(...schema._examples);
|
||||
obj._meta.push(...schema._meta);
|
||||
|
||||
const inners = Object.keys(schema._inner);
|
||||
const isObject = obj._type === 'object';
|
||||
for (let i = 0; i < inners.length; ++i) {
|
||||
const key = inners[i];
|
||||
const source = schema._inner[key];
|
||||
if (source) {
|
||||
const target = obj._inner[key];
|
||||
if (target) {
|
||||
if (isObject && key === 'children') {
|
||||
const keys = {};
|
||||
|
||||
for (let j = 0; j < target.length; ++j) {
|
||||
keys[target[j].key] = j;
|
||||
}
|
||||
|
||||
for (let j = 0; j < source.length; ++j) {
|
||||
const sourceKey = source[j].key;
|
||||
if (keys[sourceKey] >= 0) {
|
||||
target[keys[sourceKey]] = {
|
||||
key: sourceKey,
|
||||
schema: target[keys[sourceKey]].schema.concat(source[j].schema)
|
||||
};
|
||||
}
|
||||
else {
|
||||
target.push(source[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
obj._inner[key] = obj._inner[key].concat(source);
|
||||
}
|
||||
}
|
||||
else {
|
||||
obj._inner[key] = source.slice();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
_test(name, arg, func, options) {
|
||||
|
||||
const obj = this.clone();
|
||||
obj._tests.push({ func, name, arg, options });
|
||||
return obj;
|
||||
}
|
||||
|
||||
_testUnique(name, arg, func, options) {
|
||||
|
||||
const obj = this.clone();
|
||||
obj._tests = obj._tests.filter((test) => test.name !== name);
|
||||
obj._tests.push({ func, name, arg, options });
|
||||
return obj;
|
||||
}
|
||||
|
||||
options(options) {
|
||||
|
||||
Hoek.assert(!options.context, 'Cannot override context');
|
||||
this.checkOptions(options);
|
||||
|
||||
const obj = this.clone();
|
||||
obj._settings = Settings.concat(obj._settings, options);
|
||||
return obj;
|
||||
}
|
||||
|
||||
strict(isStrict) {
|
||||
|
||||
const obj = this.clone();
|
||||
|
||||
const convert = isStrict === undefined ? false : !isStrict;
|
||||
obj._settings = Settings.concat(obj._settings, { convert });
|
||||
return obj;
|
||||
}
|
||||
|
||||
raw(isRaw) {
|
||||
|
||||
const value = isRaw === undefined ? true : isRaw;
|
||||
|
||||
if (this._flags.raw === value) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.raw = value;
|
||||
return obj;
|
||||
}
|
||||
|
||||
error(err, options = { self: false }) {
|
||||
|
||||
Hoek.assert(err && (err instanceof Error || typeof err === 'function'), 'Must provide a valid Error object or a function');
|
||||
|
||||
const unknownKeys = Object.keys(options).filter((k) => !['self'].includes(k));
|
||||
Hoek.assert(unknownKeys.length === 0, `Options ${unknownKeys} are unknown`);
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.error = err;
|
||||
|
||||
if (options.self) {
|
||||
obj._flags.selfError = true;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
allow(...values) {
|
||||
|
||||
const obj = this.clone();
|
||||
values = Hoek.flatten(values);
|
||||
for (let i = 0; i < values.length; ++i) {
|
||||
const value = values[i];
|
||||
|
||||
Hoek.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');
|
||||
obj._invalids.remove(value);
|
||||
obj._valids.add(value, obj._refs);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
valid(...values) {
|
||||
|
||||
const obj = this.allow(...values);
|
||||
obj._flags.allowOnly = true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
invalid(...values) {
|
||||
|
||||
const obj = this.clone();
|
||||
values = Hoek.flatten(values);
|
||||
for (let i = 0; i < values.length; ++i) {
|
||||
const value = values[i];
|
||||
|
||||
Hoek.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');
|
||||
obj._valids.remove(value);
|
||||
obj._invalids.add(value, obj._refs);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
required() {
|
||||
|
||||
if (this._flags.presence === 'required') {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.presence = 'required';
|
||||
return obj;
|
||||
}
|
||||
|
||||
optional() {
|
||||
|
||||
if (this._flags.presence === 'optional') {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.presence = 'optional';
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
forbidden() {
|
||||
|
||||
if (this._flags.presence === 'forbidden') {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.presence = 'forbidden';
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
strip() {
|
||||
|
||||
if (this._flags.strip) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.strip = true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
applyFunctionToChildren(children, fn, args = [], root) {
|
||||
|
||||
children = [].concat(children);
|
||||
|
||||
if (children.length !== 1 || children[0] !== '') {
|
||||
root = root ? (root + '.') : '';
|
||||
|
||||
const extraChildren = (children[0] === '' ? children.slice(1) : children).map((child) => {
|
||||
|
||||
return root + child;
|
||||
});
|
||||
|
||||
throw new Error('unknown key(s) ' + extraChildren.join(', '));
|
||||
}
|
||||
|
||||
return this[fn](...args);
|
||||
}
|
||||
|
||||
default(value, description) {
|
||||
|
||||
if (typeof value === 'function' &&
|
||||
!Ref.isRef(value)) {
|
||||
|
||||
if (!value.description &&
|
||||
description) {
|
||||
|
||||
value.description = description;
|
||||
}
|
||||
|
||||
if (!this._flags.func) {
|
||||
Hoek.assert(typeof value.description === 'string' && value.description.length > 0, 'description must be provided when default value is a function');
|
||||
}
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.default = value;
|
||||
Ref.push(obj._refs, value);
|
||||
return obj;
|
||||
}
|
||||
|
||||
empty(schema) {
|
||||
|
||||
const obj = this.clone();
|
||||
if (schema === undefined) {
|
||||
delete obj._flags.empty;
|
||||
}
|
||||
else {
|
||||
obj._flags.empty = Cast.schema(this._currentJoi, schema);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
when(condition, options) {
|
||||
|
||||
Hoek.assert(options && typeof options === 'object', 'Invalid options');
|
||||
Hoek.assert(options.then !== undefined || options.otherwise !== undefined, 'options must have at least one of "then" or "otherwise"');
|
||||
|
||||
const then = options.hasOwnProperty('then') ? this.concat(Cast.schema(this._currentJoi, options.then)) : undefined;
|
||||
const otherwise = options.hasOwnProperty('otherwise') ? this.concat(Cast.schema(this._currentJoi, options.otherwise)) : undefined;
|
||||
|
||||
Alternatives = Alternatives || require('../alternatives');
|
||||
|
||||
const alternativeOptions = { then, otherwise };
|
||||
if (Object.prototype.hasOwnProperty.call(options, 'is')) {
|
||||
alternativeOptions.is = options.is;
|
||||
}
|
||||
|
||||
const obj = Alternatives.when(condition, alternativeOptions);
|
||||
obj._flags.presence = 'ignore';
|
||||
obj._baseType = this;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
description(desc) {
|
||||
|
||||
Hoek.assert(desc && typeof desc === 'string', 'Description must be a non-empty string');
|
||||
|
||||
const obj = this.clone();
|
||||
obj._description = desc;
|
||||
return obj;
|
||||
}
|
||||
|
||||
notes(notes) {
|
||||
|
||||
Hoek.assert(notes && (typeof notes === 'string' || Array.isArray(notes)), 'Notes must be a non-empty string or array');
|
||||
|
||||
const obj = this.clone();
|
||||
obj._notes = obj._notes.concat(notes);
|
||||
return obj;
|
||||
}
|
||||
|
||||
tags(tags) {
|
||||
|
||||
Hoek.assert(tags && (typeof tags === 'string' || Array.isArray(tags)), 'Tags must be a non-empty string or array');
|
||||
|
||||
const obj = this.clone();
|
||||
obj._tags = obj._tags.concat(tags);
|
||||
return obj;
|
||||
}
|
||||
|
||||
meta(meta) {
|
||||
|
||||
Hoek.assert(meta !== undefined, 'Meta cannot be undefined');
|
||||
|
||||
const obj = this.clone();
|
||||
obj._meta = obj._meta.concat(meta);
|
||||
return obj;
|
||||
}
|
||||
|
||||
example(...examples) {
|
||||
|
||||
Hoek.assert(examples.length > 0, 'Missing examples');
|
||||
|
||||
const processed = [];
|
||||
for (let i = 0; i < examples.length; ++i) {
|
||||
const example = [].concat(examples[i]);
|
||||
Hoek.assert(example.length <= 2, `Bad example format at index ${i}`);
|
||||
|
||||
const value = example[0];
|
||||
let options = example[1];
|
||||
if (options !== undefined) {
|
||||
Hoek.assert(options && typeof options === 'object', `Options for example at index ${i} must be an object`);
|
||||
const unknownOptions = Object.keys(options).filter((option) => !['parent', 'context'].includes(option));
|
||||
Hoek.assert(unknownOptions.length === 0, `Unknown example options ${unknownOptions} at index ${i}`);
|
||||
}
|
||||
else {
|
||||
options = {};
|
||||
}
|
||||
|
||||
const localState = new State('', [], options.parent || null);
|
||||
const result = this._validate(value, localState, Settings.concat(internals.defaults, options.context ? { context: options.context } : null));
|
||||
Hoek.assert(!result.errors, `Bad example at index ${i}:`, result.errors && Errors.process(result.errors, value));
|
||||
|
||||
const ex = { value };
|
||||
if (Object.keys(options).length) {
|
||||
ex.options = options;
|
||||
}
|
||||
|
||||
processed.push(ex);
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._examples = processed;
|
||||
return obj;
|
||||
}
|
||||
|
||||
unit(name) {
|
||||
|
||||
Hoek.assert(name && typeof name === 'string', 'Unit name must be a non-empty string');
|
||||
|
||||
const obj = this.clone();
|
||||
obj._unit = name;
|
||||
return obj;
|
||||
}
|
||||
|
||||
_prepareEmptyValue(value) {
|
||||
|
||||
if (typeof value === 'string' && this._flags.trim) {
|
||||
return value.trim();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
_validate(value, state, options, reference) {
|
||||
|
||||
const originalValue = value;
|
||||
|
||||
// Setup state and settings
|
||||
|
||||
state = state || new State('', [], null, reference);
|
||||
|
||||
if (this._settings) {
|
||||
const isDefaultOptions = options === internals.defaults;
|
||||
if (isDefaultOptions && this._settings[Symbols.settingsCache]) {
|
||||
options = this._settings[Symbols.settingsCache];
|
||||
}
|
||||
else {
|
||||
options = Settings.concat(this._language ? Settings.concat({ language: this._language }, options) : options, this._settings);
|
||||
if (isDefaultOptions) {
|
||||
this._settings[Symbols.settingsCache] = options;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this._language) {
|
||||
options = Settings.concat({ language: this._language }, options);
|
||||
}
|
||||
|
||||
let errors = [];
|
||||
|
||||
if (this._coerce) {
|
||||
const coerced = this._coerce(value, state, options);
|
||||
if (coerced.errors) {
|
||||
value = coerced.value;
|
||||
errors = errors.concat(coerced.errors);
|
||||
return this._finalizeValue(value, originalValue, errors, state, options); // Coerced error always aborts early
|
||||
}
|
||||
|
||||
value = coerced.value;
|
||||
}
|
||||
|
||||
if (this._flags.empty && !this._flags.empty._validate(this._prepareEmptyValue(value), null, internals.defaults).errors) {
|
||||
value = undefined;
|
||||
}
|
||||
|
||||
// Check presence requirements
|
||||
|
||||
const presence = this._flags.presence || options.presence;
|
||||
if (presence === 'optional') {
|
||||
if (value === undefined) {
|
||||
const isDeepDefault = this._flags.hasOwnProperty('default') && this._flags.default === undefined;
|
||||
if (isDeepDefault && this._type === 'object') {
|
||||
value = {};
|
||||
}
|
||||
else {
|
||||
return this._finalizeValue(value, originalValue, errors, state, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (presence === 'required' &&
|
||||
value === undefined) {
|
||||
|
||||
errors.push(this.createError('any.required', null, state, options));
|
||||
return this._finalizeValue(value, originalValue, errors, state, options);
|
||||
}
|
||||
else if (presence === 'forbidden') {
|
||||
if (value === undefined) {
|
||||
return this._finalizeValue(value, originalValue, errors, state, options);
|
||||
}
|
||||
|
||||
errors.push(this.createError('any.unknown', null, state, options));
|
||||
return this._finalizeValue(value, originalValue, errors, state, options);
|
||||
}
|
||||
|
||||
// Check allowed and denied values using the original value
|
||||
|
||||
let match = this._valids.get(value, state, options, this._flags.insensitive);
|
||||
if (match) {
|
||||
if (options.convert) {
|
||||
value = match.value;
|
||||
}
|
||||
|
||||
return this._finalizeValue(value, originalValue, errors, state, options);
|
||||
}
|
||||
|
||||
if (this._invalids.has(value, state, options, this._flags.insensitive)) {
|
||||
errors.push(this.createError(value === '' ? 'any.empty' : 'any.invalid', { value, invalids: this._invalids.values({ stripUndefined: true }) }, state, options));
|
||||
if (options.abortEarly) {
|
||||
|
||||
return this._finalizeValue(value, originalValue, errors, state, options);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert value and validate type
|
||||
|
||||
if (this._base) {
|
||||
const base = this._base(value, state, options);
|
||||
if (base.errors) {
|
||||
value = base.value;
|
||||
errors = errors.concat(base.errors);
|
||||
return this._finalizeValue(value, originalValue, errors, state, options); // Base error always aborts early
|
||||
}
|
||||
|
||||
if (base.value !== value) {
|
||||
value = base.value;
|
||||
|
||||
// Check allowed and denied values using the converted value
|
||||
|
||||
match = this._valids.get(value, state, options, this._flags.insensitive);
|
||||
if (match) {
|
||||
value = match.value;
|
||||
return this._finalizeValue(value, originalValue, errors, state, options);
|
||||
}
|
||||
|
||||
if (this._invalids.has(value, state, options, this._flags.insensitive)) {
|
||||
errors.push(this.createError(value === '' ? 'any.empty' : 'any.invalid', { value, invalids: this._invalids.values({ stripUndefined: true }) }, state, options));
|
||||
if (options.abortEarly) {
|
||||
return this._finalizeValue(value, originalValue, errors, state, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Required values did not match
|
||||
|
||||
if (this._flags.allowOnly) {
|
||||
errors.push(this.createError('any.allowOnly', { value, valids: this._valids.values({ stripUndefined: true }) }, state, options));
|
||||
if (options.abortEarly) {
|
||||
return this._finalizeValue(value, originalValue, errors, state, options);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate tests
|
||||
|
||||
for (let i = 0; i < this._tests.length; ++i) {
|
||||
const test = this._tests[i];
|
||||
const ret = test.func.call(this, value, state, options);
|
||||
if (ret instanceof Errors.Err) {
|
||||
errors.push(ret);
|
||||
if (options.abortEarly) {
|
||||
return this._finalizeValue(value, originalValue, errors, state, options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
value = ret;
|
||||
}
|
||||
}
|
||||
|
||||
return this._finalizeValue(value, originalValue, errors, state, options);
|
||||
}
|
||||
|
||||
_finalizeValue(value, originalValue, errors, state, options) {
|
||||
|
||||
let finalValue;
|
||||
|
||||
if (value !== undefined) {
|
||||
finalValue = this._flags.raw ? originalValue : value;
|
||||
}
|
||||
else if (options.noDefaults) {
|
||||
finalValue = value;
|
||||
}
|
||||
else if (Ref.isRef(this._flags.default)) {
|
||||
finalValue = this._flags.default(state.parent, options);
|
||||
}
|
||||
else if (typeof this._flags.default === 'function' &&
|
||||
!(this._flags.func && !this._flags.default.description)) {
|
||||
|
||||
let args;
|
||||
|
||||
if (state.parent !== null &&
|
||||
this._flags.default.length > 0) {
|
||||
|
||||
args = [Hoek.clone(state.parent), options];
|
||||
}
|
||||
|
||||
const defaultValue = internals._try(this._flags.default, args);
|
||||
finalValue = defaultValue.value;
|
||||
if (defaultValue.error) {
|
||||
errors.push(this.createError('any.default', { error: defaultValue.error }, state, options));
|
||||
}
|
||||
}
|
||||
else {
|
||||
finalValue = Hoek.clone(this._flags.default);
|
||||
}
|
||||
|
||||
if (errors.length &&
|
||||
typeof this._flags.error === 'function' &&
|
||||
(
|
||||
!this._flags.selfError ||
|
||||
errors.some((e) => state.path.length === e.path.length)
|
||||
)
|
||||
) {
|
||||
const change = this._flags.error.call(this, errors);
|
||||
|
||||
if (typeof change === 'string') {
|
||||
errors = [this.createOverrideError('override', { reason: errors }, state, options, change)];
|
||||
}
|
||||
else {
|
||||
errors = [].concat(change)
|
||||
.map((err) => {
|
||||
|
||||
return err instanceof Error ?
|
||||
err :
|
||||
this.createOverrideError(err.type || 'override', err.context, state, options, err.message, err.template);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
value: this._flags.strip ? undefined : finalValue,
|
||||
finalValue,
|
||||
errors: errors.length ? errors : null
|
||||
};
|
||||
}
|
||||
|
||||
_validateWithOptions(value, options, callback) {
|
||||
|
||||
if (options) {
|
||||
this.checkOptions(options);
|
||||
}
|
||||
|
||||
const settings = Settings.concat(internals.defaults, options);
|
||||
const result = this._validate(value, null, settings);
|
||||
const errors = Errors.process(result.errors, value);
|
||||
|
||||
if (callback) {
|
||||
return callback(errors, result.value);
|
||||
}
|
||||
|
||||
return {
|
||||
error: errors,
|
||||
value: result.value,
|
||||
then(resolve, reject) {
|
||||
|
||||
if (errors) {
|
||||
return Promise.reject(errors).catch(reject);
|
||||
}
|
||||
|
||||
return Promise.resolve(result.value).then(resolve);
|
||||
},
|
||||
catch(reject) {
|
||||
|
||||
if (errors) {
|
||||
return Promise.reject(errors).catch(reject);
|
||||
}
|
||||
|
||||
return Promise.resolve(result.value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
validate(value, options, callback) {
|
||||
|
||||
if (typeof options === 'function') {
|
||||
return this._validateWithOptions(value, null, options);
|
||||
}
|
||||
|
||||
return this._validateWithOptions(value, options, callback);
|
||||
}
|
||||
|
||||
describe() {
|
||||
|
||||
const description = {
|
||||
type: this._type
|
||||
};
|
||||
|
||||
const flags = Object.keys(this._flags);
|
||||
if (flags.length) {
|
||||
if (['empty', 'default', 'lazy', 'label'].some((flag) => this._flags.hasOwnProperty(flag))) {
|
||||
description.flags = {};
|
||||
for (let i = 0; i < flags.length; ++i) {
|
||||
const flag = flags[i];
|
||||
if (flag === 'empty') {
|
||||
description.flags[flag] = this._flags[flag].describe();
|
||||
}
|
||||
else if (flag === 'default') {
|
||||
if (Ref.isRef(this._flags[flag])) {
|
||||
description.flags[flag] = this._flags[flag].toString();
|
||||
}
|
||||
else if (typeof this._flags[flag] === 'function') {
|
||||
description.flags[flag] = {
|
||||
description: this._flags[flag].description,
|
||||
function : this._flags[flag]
|
||||
};
|
||||
}
|
||||
else {
|
||||
description.flags[flag] = this._flags[flag];
|
||||
}
|
||||
}
|
||||
else if (flag === 'lazy' || flag === 'label') {
|
||||
// We don't want it in the description
|
||||
}
|
||||
else {
|
||||
description.flags[flag] = this._flags[flag];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
description.flags = this._flags;
|
||||
}
|
||||
}
|
||||
|
||||
if (this._settings) {
|
||||
description.options = Hoek.clone(this._settings);
|
||||
}
|
||||
|
||||
if (this._baseType) {
|
||||
description.base = this._baseType.describe();
|
||||
}
|
||||
|
||||
if (this._description) {
|
||||
description.description = this._description;
|
||||
}
|
||||
|
||||
if (this._notes.length) {
|
||||
description.notes = this._notes;
|
||||
}
|
||||
|
||||
if (this._tags.length) {
|
||||
description.tags = this._tags;
|
||||
}
|
||||
|
||||
if (this._meta.length) {
|
||||
description.meta = this._meta;
|
||||
}
|
||||
|
||||
if (this._examples.length) {
|
||||
description.examples = this._examples;
|
||||
}
|
||||
|
||||
if (this._unit) {
|
||||
description.unit = this._unit;
|
||||
}
|
||||
|
||||
const valids = this._valids.values();
|
||||
if (valids.length) {
|
||||
description.valids = valids.map((v) => {
|
||||
|
||||
return Ref.isRef(v) ? v.toString() : v;
|
||||
});
|
||||
}
|
||||
|
||||
const invalids = this._invalids.values();
|
||||
if (invalids.length) {
|
||||
description.invalids = invalids.map((v) => {
|
||||
|
||||
return Ref.isRef(v) ? v.toString() : v;
|
||||
});
|
||||
}
|
||||
|
||||
description.rules = [];
|
||||
|
||||
for (let i = 0; i < this._tests.length; ++i) {
|
||||
const validator = this._tests[i];
|
||||
const item = { name: validator.name };
|
||||
|
||||
if (validator.arg !== void 0) {
|
||||
item.arg = Ref.isRef(validator.arg) ? validator.arg.toString() : validator.arg;
|
||||
}
|
||||
|
||||
const options = validator.options;
|
||||
if (options) {
|
||||
if (options.hasRef) {
|
||||
item.arg = {};
|
||||
const keys = Object.keys(validator.arg);
|
||||
for (let j = 0; j < keys.length; ++j) {
|
||||
const key = keys[j];
|
||||
const value = validator.arg[key];
|
||||
item.arg[key] = Ref.isRef(value) ? value.toString() : value;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof options.description === 'string') {
|
||||
item.description = options.description;
|
||||
}
|
||||
else if (typeof options.description === 'function') {
|
||||
item.description = options.description(item.arg);
|
||||
}
|
||||
}
|
||||
|
||||
description.rules.push(item);
|
||||
}
|
||||
|
||||
if (!description.rules.length) {
|
||||
delete description.rules;
|
||||
}
|
||||
|
||||
const label = this._getLabel();
|
||||
if (label) {
|
||||
description.label = label;
|
||||
}
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
label(name) {
|
||||
|
||||
Hoek.assert(name && typeof name === 'string', 'Label name must be a non-empty string');
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.label = name;
|
||||
return obj;
|
||||
}
|
||||
|
||||
_getLabel(def) {
|
||||
|
||||
return this._flags.label || def;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
internals.Any.prototype.isImmutable = true; // Prevents Hoek from deep cloning schema objects
|
||||
|
||||
// Aliases
|
||||
|
||||
internals.Any.prototype.only = internals.Any.prototype.equal = internals.Any.prototype.valid;
|
||||
internals.Any.prototype.disallow = internals.Any.prototype.not = internals.Any.prototype.invalid;
|
||||
internals.Any.prototype.exist = internals.Any.prototype.required;
|
||||
|
||||
|
||||
internals.Any.prototype[internals.symbol] = {
|
||||
version: Pkg.version,
|
||||
compile: Cast.schema,
|
||||
root: '_currentJoi'
|
||||
};
|
||||
|
||||
|
||||
internals._try = function (fn, args = []) {
|
||||
|
||||
let err;
|
||||
let result;
|
||||
|
||||
try {
|
||||
result = fn(...args);
|
||||
}
|
||||
catch (e) {
|
||||
err = e;
|
||||
}
|
||||
|
||||
return {
|
||||
value: result,
|
||||
error: err
|
||||
};
|
||||
};
|
32
web/node_modules/@hapi/joi/lib/types/any/settings.js
generated
vendored
Executable file
32
web/node_modules/@hapi/joi/lib/types/any/settings.js
generated
vendored
Executable file
|
@ -0,0 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Symbols = require('../symbols');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
exports.concat = function (target, source) {
|
||||
|
||||
if (!source) {
|
||||
return target;
|
||||
}
|
||||
|
||||
const obj = Object.assign({}, target);
|
||||
|
||||
const language = source.language;
|
||||
|
||||
Object.assign(obj, source);
|
||||
|
||||
if (language && target && target.language) {
|
||||
obj.language = Hoek.applyToDefaults(target.language, language);
|
||||
}
|
||||
|
||||
if (obj[Symbols.settingsCache]) {
|
||||
delete obj[Symbols.settingsCache];
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
699
web/node_modules/@hapi/joi/lib/types/array/index.js
generated
vendored
Executable file
699
web/node_modules/@hapi/joi/lib/types/array/index.js
generated
vendored
Executable file
|
@ -0,0 +1,699 @@
|
|||
'use strict';
|
||||
|
||||
const Bourne = require('@hapi/bourne');
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Any = require('../any');
|
||||
const Cast = require('../../cast');
|
||||
const Ref = require('../../ref');
|
||||
const State = require('../state');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
internals.fastSplice = function (arr, i) {
|
||||
|
||||
let pos = i;
|
||||
while (pos < arr.length) {
|
||||
arr[pos++] = arr[pos];
|
||||
}
|
||||
|
||||
--arr.length;
|
||||
};
|
||||
|
||||
|
||||
internals.Array = class extends Any {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this._type = 'array';
|
||||
this._inner.items = [];
|
||||
this._inner.ordereds = [];
|
||||
this._inner.inclusions = [];
|
||||
this._inner.exclusions = [];
|
||||
this._inner.requireds = [];
|
||||
this._flags.sparse = false;
|
||||
}
|
||||
|
||||
_base(value, state, options) {
|
||||
|
||||
const result = {
|
||||
value
|
||||
};
|
||||
|
||||
if (typeof value === 'string' &&
|
||||
options.convert) {
|
||||
|
||||
if (value.length > 1 &&
|
||||
(value[0] === '[' || /^\s*\[/.test(value))) {
|
||||
|
||||
try {
|
||||
result.value = Bourne.parse(value);
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
}
|
||||
|
||||
let isArray = Array.isArray(result.value);
|
||||
const wasArray = isArray;
|
||||
if (options.convert && this._flags.single && !isArray) {
|
||||
result.value = [result.value];
|
||||
isArray = true;
|
||||
}
|
||||
|
||||
if (!isArray) {
|
||||
result.errors = this.createError('array.base', null, state, options);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (this._inner.inclusions.length ||
|
||||
this._inner.exclusions.length ||
|
||||
this._inner.requireds.length ||
|
||||
this._inner.ordereds.length ||
|
||||
!this._flags.sparse) {
|
||||
|
||||
// Clone the array so that we don't modify the original
|
||||
if (wasArray) {
|
||||
result.value = result.value.slice(0);
|
||||
}
|
||||
|
||||
result.errors = this._checkItems(result.value, wasArray, state, options);
|
||||
|
||||
if (result.errors && wasArray && options.convert && this._flags.single) {
|
||||
|
||||
// Attempt a 2nd pass by putting the array inside one.
|
||||
const previousErrors = result.errors;
|
||||
|
||||
result.value = [result.value];
|
||||
result.errors = this._checkItems(result.value, wasArray, state, options);
|
||||
|
||||
if (result.errors) {
|
||||
|
||||
// Restore previous errors and value since this didn't validate either.
|
||||
result.errors = previousErrors;
|
||||
result.value = result.value[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
_checkItems(items, wasArray, state, options) {
|
||||
|
||||
const errors = [];
|
||||
let errored;
|
||||
|
||||
const requireds = this._inner.requireds.slice();
|
||||
const ordereds = this._inner.ordereds.slice();
|
||||
const inclusions = [...this._inner.inclusions, ...requireds];
|
||||
|
||||
let il = items.length;
|
||||
for (let i = 0; i < il; ++i) {
|
||||
errored = false;
|
||||
const item = items[i];
|
||||
let isValid = false;
|
||||
const key = wasArray ? i : state.key;
|
||||
const path = wasArray ? [...state.path, i] : state.path;
|
||||
const localState = new State(key, path, state.parent, state.reference);
|
||||
let res;
|
||||
|
||||
// Sparse
|
||||
|
||||
if (!this._flags.sparse && item === undefined) {
|
||||
errors.push(this.createError('array.sparse', null, { key: state.key, path: localState.path, pos: i }, options));
|
||||
|
||||
if (options.abortEarly) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
ordereds.shift();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Exclusions
|
||||
|
||||
for (let j = 0; j < this._inner.exclusions.length; ++j) {
|
||||
res = this._inner.exclusions[j]._validate(item, localState, {}); // Not passing options to use defaults
|
||||
|
||||
if (!res.errors) {
|
||||
errors.push(this.createError(wasArray ? 'array.excludes' : 'array.excludesSingle', { pos: i, value: item }, { key: state.key, path: localState.path }, options));
|
||||
errored = true;
|
||||
|
||||
if (options.abortEarly) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
ordereds.shift();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (errored) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ordered
|
||||
if (this._inner.ordereds.length) {
|
||||
if (ordereds.length > 0) {
|
||||
const ordered = ordereds.shift();
|
||||
res = ordered._validate(item, localState, options);
|
||||
if (!res.errors) {
|
||||
if (ordered._flags.strip) {
|
||||
internals.fastSplice(items, i);
|
||||
--i;
|
||||
--il;
|
||||
}
|
||||
else if (!this._flags.sparse && res.value === undefined) {
|
||||
errors.push(this.createError('array.sparse', null, { key: state.key, path: localState.path, pos: i }, options));
|
||||
|
||||
if (options.abortEarly) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
items[i] = res.value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
errors.push(this.createError('array.ordered', { pos: i, reason: res.errors, value: item }, { key: state.key, path: localState.path }, options));
|
||||
if (options.abortEarly) {
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (!this._inner.items.length) {
|
||||
errors.push(this.createError('array.orderedLength', { pos: i, limit: this._inner.ordereds.length }, { key: state.key, path: localState.path }, options));
|
||||
if (options.abortEarly) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Requireds
|
||||
|
||||
const requiredChecks = [];
|
||||
let jl = requireds.length;
|
||||
for (let j = 0; j < jl; ++j) {
|
||||
res = requiredChecks[j] = requireds[j]._validate(item, localState, options);
|
||||
if (!res.errors) {
|
||||
items[i] = res.value;
|
||||
isValid = true;
|
||||
internals.fastSplice(requireds, j);
|
||||
--j;
|
||||
--jl;
|
||||
|
||||
if (!this._flags.sparse && res.value === undefined) {
|
||||
errors.push(this.createError('array.sparse', null, { key: state.key, path: localState.path, pos: i }, options));
|
||||
|
||||
if (options.abortEarly) {
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Inclusions
|
||||
|
||||
const stripUnknown = options.stripUnknown && !!options.stripUnknown.arrays || false;
|
||||
|
||||
jl = inclusions.length;
|
||||
for (let j = 0; j < jl; ++j) {
|
||||
const inclusion = inclusions[j];
|
||||
|
||||
// Avoid re-running requireds that already didn't match in the previous loop
|
||||
const previousCheck = requireds.indexOf(inclusion);
|
||||
if (previousCheck !== -1) {
|
||||
res = requiredChecks[previousCheck];
|
||||
}
|
||||
else {
|
||||
res = inclusion._validate(item, localState, options);
|
||||
|
||||
if (!res.errors) {
|
||||
if (inclusion._flags.strip) {
|
||||
internals.fastSplice(items, i);
|
||||
--i;
|
||||
--il;
|
||||
}
|
||||
else if (!this._flags.sparse && res.value === undefined) {
|
||||
errors.push(this.createError('array.sparse', null, { key: state.key, path: localState.path, pos: i }, options));
|
||||
errored = true;
|
||||
}
|
||||
else {
|
||||
items[i] = res.value;
|
||||
}
|
||||
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the actual error if only one inclusion defined
|
||||
if (jl === 1) {
|
||||
if (stripUnknown) {
|
||||
internals.fastSplice(items, i);
|
||||
--i;
|
||||
--il;
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
errors.push(this.createError(wasArray ? 'array.includesOne' : 'array.includesOneSingle', { pos: i, reason: res.errors, value: item }, { key: state.key, path: localState.path }, options));
|
||||
errored = true;
|
||||
|
||||
if (options.abortEarly) {
|
||||
return errors;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (errored) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this._inner.inclusions.length && !isValid) {
|
||||
if (stripUnknown) {
|
||||
internals.fastSplice(items, i);
|
||||
--i;
|
||||
--il;
|
||||
continue;
|
||||
}
|
||||
|
||||
errors.push(this.createError(wasArray ? 'array.includes' : 'array.includesSingle', { pos: i, value: item }, { key: state.key, path: localState.path }, options));
|
||||
|
||||
if (options.abortEarly) {
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (requireds.length) {
|
||||
this._fillMissedErrors(errors, requireds, state, options);
|
||||
}
|
||||
|
||||
if (ordereds.length) {
|
||||
this._fillOrderedErrors(errors, ordereds, state, options);
|
||||
}
|
||||
|
||||
return errors.length ? errors : null;
|
||||
}
|
||||
|
||||
describe() {
|
||||
|
||||
const description = super.describe();
|
||||
|
||||
if (this._inner.ordereds.length) {
|
||||
description.orderedItems = [];
|
||||
|
||||
for (let i = 0; i < this._inner.ordereds.length; ++i) {
|
||||
description.orderedItems.push(this._inner.ordereds[i].describe());
|
||||
}
|
||||
}
|
||||
|
||||
if (this._inner.items.length) {
|
||||
description.items = [];
|
||||
|
||||
for (let i = 0; i < this._inner.items.length; ++i) {
|
||||
description.items.push(this._inner.items[i].describe());
|
||||
}
|
||||
}
|
||||
|
||||
if (description.rules) {
|
||||
for (let i = 0; i < description.rules.length; ++i) {
|
||||
const rule = description.rules[i];
|
||||
if (rule.name === 'has') {
|
||||
rule.arg = rule.arg.describe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
items(...schemas) {
|
||||
|
||||
const obj = this.clone();
|
||||
|
||||
Hoek.flatten(schemas).forEach((type, index) => {
|
||||
|
||||
try {
|
||||
type = Cast.schema(this._currentJoi, type);
|
||||
}
|
||||
catch (castErr) {
|
||||
if (castErr.hasOwnProperty('path')) {
|
||||
castErr.path = index + '.' + castErr.path;
|
||||
}
|
||||
else {
|
||||
castErr.path = index;
|
||||
}
|
||||
|
||||
castErr.message = `${castErr.message}(${castErr.path})`;
|
||||
throw castErr;
|
||||
}
|
||||
|
||||
obj._inner.items.push(type);
|
||||
|
||||
if (type._flags.presence === 'required') {
|
||||
obj._inner.requireds.push(type);
|
||||
}
|
||||
else if (type._flags.presence === 'forbidden') {
|
||||
obj._inner.exclusions.push(type.optional());
|
||||
}
|
||||
else {
|
||||
obj._inner.inclusions.push(type);
|
||||
}
|
||||
});
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
ordered(...schemas) {
|
||||
|
||||
const obj = this.clone();
|
||||
|
||||
Hoek.flatten(schemas).forEach((type, index) => {
|
||||
|
||||
try {
|
||||
type = Cast.schema(this._currentJoi, type);
|
||||
}
|
||||
catch (castErr) {
|
||||
if (castErr.hasOwnProperty('path')) {
|
||||
castErr.path = index + '.' + castErr.path;
|
||||
}
|
||||
else {
|
||||
castErr.path = index;
|
||||
}
|
||||
|
||||
castErr.message = `${castErr.message}(${castErr.path})`;
|
||||
throw castErr;
|
||||
}
|
||||
|
||||
obj._inner.ordereds.push(type);
|
||||
});
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
min(limit) {
|
||||
|
||||
const isRef = Ref.isRef(limit);
|
||||
|
||||
Hoek.assert((Number.isSafeInteger(limit) && limit >= 0) || isRef, 'limit must be a positive integer or reference');
|
||||
|
||||
return this._testUnique('min', limit, function (value, state, options) {
|
||||
|
||||
let compareTo;
|
||||
if (isRef) {
|
||||
compareTo = limit(state.reference || state.parent, options);
|
||||
|
||||
if (!(Number.isSafeInteger(compareTo) && compareTo >= 0)) {
|
||||
return this.createError('array.ref', { ref: limit, value: compareTo }, state, options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
compareTo = limit;
|
||||
}
|
||||
|
||||
if (value.length >= compareTo) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('array.min', { limit, value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
max(limit) {
|
||||
|
||||
const isRef = Ref.isRef(limit);
|
||||
|
||||
Hoek.assert((Number.isSafeInteger(limit) && limit >= 0) || isRef, 'limit must be a positive integer or reference');
|
||||
|
||||
return this._testUnique('max', limit, function (value, state, options) {
|
||||
|
||||
let compareTo;
|
||||
if (isRef) {
|
||||
compareTo = limit(state.reference || state.parent, options);
|
||||
|
||||
if (!(Number.isSafeInteger(compareTo) && compareTo >= 0)) {
|
||||
return this.createError('array.ref', { ref: limit.key }, state, options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
compareTo = limit;
|
||||
}
|
||||
|
||||
if (value.length <= compareTo) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('array.max', { limit, value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
length(limit) {
|
||||
|
||||
const isRef = Ref.isRef(limit);
|
||||
|
||||
Hoek.assert((Number.isSafeInteger(limit) && limit >= 0) || isRef, 'limit must be a positive integer or reference');
|
||||
|
||||
return this._testUnique('length', limit, function (value, state, options) {
|
||||
|
||||
let compareTo;
|
||||
if (isRef) {
|
||||
compareTo = limit(state.reference || state.parent, options);
|
||||
|
||||
if (!(Number.isSafeInteger(compareTo) && compareTo >= 0)) {
|
||||
return this.createError('array.ref', { ref: limit.key }, state, options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
compareTo = limit;
|
||||
}
|
||||
|
||||
if (value.length === compareTo) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('array.length', { limit, value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
has(schema) {
|
||||
|
||||
try {
|
||||
schema = Cast.schema(this._currentJoi, schema);
|
||||
}
|
||||
catch (castErr) {
|
||||
if (castErr.hasOwnProperty('path')) {
|
||||
castErr.message = `${castErr.message}(${castErr.path})`;
|
||||
}
|
||||
|
||||
throw castErr;
|
||||
}
|
||||
|
||||
return this._test('has', schema, function (value, state, options) {
|
||||
|
||||
const isValid = value.some((item, idx) => {
|
||||
|
||||
const localState = new State(idx, [...state.path, idx], state.key, state.reference);
|
||||
return !schema._validate(item, localState, options).errors;
|
||||
});
|
||||
|
||||
if (isValid) {
|
||||
return value;
|
||||
}
|
||||
|
||||
const patternLabel = schema._getLabel();
|
||||
if (patternLabel) {
|
||||
return this.createError('array.hasKnown', { patternLabel }, state, options);
|
||||
}
|
||||
|
||||
return this.createError('array.hasUnknown', null, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
unique(comparator, configs) {
|
||||
|
||||
Hoek.assert(comparator === undefined ||
|
||||
typeof comparator === 'function' ||
|
||||
typeof comparator === 'string', 'comparator must be a function or a string');
|
||||
|
||||
Hoek.assert(configs === undefined ||
|
||||
typeof configs === 'object', 'configs must be an object');
|
||||
|
||||
const settings = {
|
||||
ignoreUndefined: (configs && configs.ignoreUndefined) || false
|
||||
};
|
||||
|
||||
|
||||
if (typeof comparator === 'string') {
|
||||
settings.path = comparator;
|
||||
}
|
||||
else if (typeof comparator === 'function') {
|
||||
settings.comparator = comparator;
|
||||
}
|
||||
|
||||
return this._test('unique', settings, function (value, state, options) {
|
||||
|
||||
const found = {
|
||||
string: Object.create(null),
|
||||
number: Object.create(null),
|
||||
undefined: Object.create(null),
|
||||
boolean: Object.create(null),
|
||||
object: new Map(),
|
||||
function: new Map(),
|
||||
custom: new Map()
|
||||
};
|
||||
|
||||
const compare = settings.comparator || Hoek.deepEqual;
|
||||
const ignoreUndefined = settings.ignoreUndefined;
|
||||
|
||||
for (let i = 0; i < value.length; ++i) {
|
||||
const item = settings.path ? Hoek.reach(value[i], settings.path) : value[i];
|
||||
const records = settings.comparator ? found.custom : found[typeof item];
|
||||
|
||||
// All available types are supported, so it's not possible to reach 100% coverage without ignoring this line.
|
||||
// I still want to keep the test for future js versions with new types (eg. Symbol).
|
||||
if (/* $lab:coverage:off$ */ records /* $lab:coverage:on$ */) {
|
||||
if (records instanceof Map) {
|
||||
const entries = records.entries();
|
||||
let current;
|
||||
while (!(current = entries.next()).done) {
|
||||
if (compare(current.value[0], item)) {
|
||||
const localState = new State(state.key, [...state.path, i], state.parent, state.reference);
|
||||
const context = {
|
||||
pos: i,
|
||||
value: value[i],
|
||||
dupePos: current.value[1],
|
||||
dupeValue: value[current.value[1]]
|
||||
};
|
||||
|
||||
if (settings.path) {
|
||||
context.path = settings.path;
|
||||
}
|
||||
|
||||
return this.createError('array.unique', context, localState, options);
|
||||
}
|
||||
}
|
||||
|
||||
records.set(item, i);
|
||||
}
|
||||
else {
|
||||
if ((!ignoreUndefined || item !== undefined) && records[item] !== undefined) {
|
||||
const localState = new State(state.key, [...state.path, i], state.parent, state.reference);
|
||||
|
||||
const context = {
|
||||
pos: i,
|
||||
value: value[i],
|
||||
dupePos: records[item],
|
||||
dupeValue: value[records[item]]
|
||||
};
|
||||
|
||||
if (settings.path) {
|
||||
context.path = settings.path;
|
||||
}
|
||||
|
||||
return this.createError('array.unique', context, localState, options);
|
||||
}
|
||||
|
||||
records[item] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
sparse(enabled) {
|
||||
|
||||
const value = enabled === undefined ? true : !!enabled;
|
||||
|
||||
if (this._flags.sparse === value) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.sparse = value;
|
||||
return obj;
|
||||
}
|
||||
|
||||
single(enabled) {
|
||||
|
||||
const value = enabled === undefined ? true : !!enabled;
|
||||
|
||||
if (this._flags.single === value) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.single = value;
|
||||
return obj;
|
||||
}
|
||||
|
||||
_fillMissedErrors(errors, requireds, state, options) {
|
||||
|
||||
const knownMisses = [];
|
||||
let unknownMisses = 0;
|
||||
for (let i = 0; i < requireds.length; ++i) {
|
||||
const label = requireds[i]._getLabel();
|
||||
if (label) {
|
||||
knownMisses.push(label);
|
||||
}
|
||||
else {
|
||||
++unknownMisses;
|
||||
}
|
||||
}
|
||||
|
||||
if (knownMisses.length) {
|
||||
if (unknownMisses) {
|
||||
errors.push(this.createError('array.includesRequiredBoth', { knownMisses, unknownMisses }, { key: state.key, path: state.path }, options));
|
||||
}
|
||||
else {
|
||||
errors.push(this.createError('array.includesRequiredKnowns', { knownMisses }, { key: state.key, path: state.path }, options));
|
||||
}
|
||||
}
|
||||
else {
|
||||
errors.push(this.createError('array.includesRequiredUnknowns', { unknownMisses }, { key: state.key, path: state.path }, options));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_fillOrderedErrors(errors, ordereds, state, options) {
|
||||
|
||||
const requiredOrdereds = [];
|
||||
|
||||
for (let i = 0; i < ordereds.length; ++i) {
|
||||
const presence = Hoek.reach(ordereds[i], '_flags.presence');
|
||||
if (presence === 'required') {
|
||||
requiredOrdereds.push(ordereds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (requiredOrdereds.length) {
|
||||
this._fillMissedErrors(errors, requiredOrdereds, state, options);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
module.exports = new internals.Array();
|
96
web/node_modules/@hapi/joi/lib/types/binary/index.js
generated
vendored
Executable file
96
web/node_modules/@hapi/joi/lib/types/binary/index.js
generated
vendored
Executable file
|
@ -0,0 +1,96 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Any = require('../any');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
internals.Binary = class extends Any {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this._type = 'binary';
|
||||
}
|
||||
|
||||
_base(value, state, options) {
|
||||
|
||||
const result = {
|
||||
value
|
||||
};
|
||||
|
||||
if (typeof value === 'string' &&
|
||||
options.convert) {
|
||||
|
||||
try {
|
||||
result.value = Buffer.from(value, this._flags.encoding);
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
|
||||
result.errors = Buffer.isBuffer(result.value) ? null : this.createError('binary.base', null, state, options);
|
||||
return result;
|
||||
}
|
||||
|
||||
encoding(encoding) {
|
||||
|
||||
Hoek.assert(Buffer.isEncoding(encoding), 'Invalid encoding:', encoding);
|
||||
|
||||
if (this._flags.encoding === encoding) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.encoding = encoding;
|
||||
return obj;
|
||||
}
|
||||
|
||||
min(limit) {
|
||||
|
||||
Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');
|
||||
|
||||
return this._test('min', limit, function (value, state, options) {
|
||||
|
||||
if (value.length >= limit) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('binary.min', { limit, value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
max(limit) {
|
||||
|
||||
Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');
|
||||
|
||||
return this._test('max', limit, function (value, state, options) {
|
||||
|
||||
if (value.length <= limit) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('binary.max', { limit, value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
length(limit) {
|
||||
|
||||
Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');
|
||||
|
||||
return this._test('length', limit, function (value, state, options) {
|
||||
|
||||
if (value.length === limit) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('binary.length', { limit, value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
module.exports = new internals.Binary();
|
97
web/node_modules/@hapi/joi/lib/types/boolean/index.js
generated
vendored
Executable file
97
web/node_modules/@hapi/joi/lib/types/boolean/index.js
generated
vendored
Executable file
|
@ -0,0 +1,97 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Any = require('../any');
|
||||
|
||||
|
||||
const internals = {
|
||||
Set: require('../../set')
|
||||
};
|
||||
|
||||
|
||||
internals.Boolean = class extends Any {
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this._type = 'boolean';
|
||||
this._flags.insensitive = true;
|
||||
this._inner.truthySet = new internals.Set();
|
||||
this._inner.falsySet = new internals.Set();
|
||||
}
|
||||
|
||||
_base(value, state, options) {
|
||||
|
||||
const result = {
|
||||
value
|
||||
};
|
||||
|
||||
if (typeof value === 'string' &&
|
||||
options.convert) {
|
||||
|
||||
const normalized = this._flags.insensitive ? value.toLowerCase() : value;
|
||||
result.value = (normalized === 'true' ? true
|
||||
: (normalized === 'false' ? false : value));
|
||||
}
|
||||
|
||||
if (typeof result.value !== 'boolean') {
|
||||
result.value = (this._inner.truthySet.has(value, null, null, this._flags.insensitive) ? true
|
||||
: (this._inner.falsySet.has(value, null, null, this._flags.insensitive) ? false : value));
|
||||
}
|
||||
|
||||
result.errors = (typeof result.value === 'boolean') ? null : this.createError('boolean.base', { value }, state, options);
|
||||
return result;
|
||||
}
|
||||
|
||||
truthy(...values) {
|
||||
|
||||
const obj = this.clone();
|
||||
values = Hoek.flatten(values);
|
||||
for (let i = 0; i < values.length; ++i) {
|
||||
const value = values[i];
|
||||
|
||||
Hoek.assert(value !== undefined, 'Cannot call truthy with undefined');
|
||||
obj._inner.truthySet.add(value);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
falsy(...values) {
|
||||
|
||||
const obj = this.clone();
|
||||
values = Hoek.flatten(values);
|
||||
for (let i = 0; i < values.length; ++i) {
|
||||
const value = values[i];
|
||||
|
||||
Hoek.assert(value !== undefined, 'Cannot call falsy with undefined');
|
||||
obj._inner.falsySet.add(value);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
insensitive(enabled) {
|
||||
|
||||
const insensitive = enabled === undefined ? true : !!enabled;
|
||||
|
||||
if (this._flags.insensitive === insensitive) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.insensitive = insensitive;
|
||||
return obj;
|
||||
}
|
||||
|
||||
describe() {
|
||||
|
||||
const description = super.describe();
|
||||
description.truthy = [true, ...this._inner.truthySet.values()];
|
||||
description.falsy = [false, ...this._inner.falsySet.values()];
|
||||
return description;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.exports = new internals.Boolean();
|
179
web/node_modules/@hapi/joi/lib/types/date/index.js
generated
vendored
Executable file
179
web/node_modules/@hapi/joi/lib/types/date/index.js
generated
vendored
Executable file
|
@ -0,0 +1,179 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Any = require('../any');
|
||||
const Ref = require('../../ref');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
internals.isoDate = /^(?:[-+]\d{2})?(?:\d{4}(?!\d{2}\b))(?:(-?)(?:(?:0[1-9]|1[0-2])(?:\1(?:[12]\d|0[1-9]|3[01]))?|W(?:[0-4]\d|5[0-2])(?:-?[1-7])?|(?:00[1-9]|0[1-9]\d|[12]\d{2}|3(?:[0-5]\d|6[1-6])))(?![T]$|[T][\d]+Z$)(?:[T\s](?:(?:(?:[01]\d|2[0-3])(?:(:?)[0-5]\d)?|24\:?00)(?:[.,]\d+(?!:))?)(?:\2[0-5]\d(?:[.,]\d+)?)?(?:[Z]|(?:[+-])(?:[01]\d|2[0-3])(?::?[0-5]\d)?)?)?)?$/;
|
||||
internals.invalidDate = new Date('');
|
||||
internals.isIsoDate = (() => {
|
||||
|
||||
const isoString = internals.isoDate.toString();
|
||||
|
||||
return (date) => {
|
||||
|
||||
return date && (date.toString() === isoString);
|
||||
};
|
||||
})();
|
||||
|
||||
internals.Date = class extends Any {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this._type = 'date';
|
||||
}
|
||||
|
||||
_base(value, state, options) {
|
||||
|
||||
const result = {
|
||||
value: (options.convert && internals.Date.toDate(value, this._flags.format, this._flags.timestamp, this._flags.multiplier)) || value
|
||||
};
|
||||
|
||||
if (result.value instanceof Date && !isNaN(result.value.getTime())) {
|
||||
result.errors = null;
|
||||
}
|
||||
else if (!options.convert) {
|
||||
result.errors = this.createError('date.strict', { value }, state, options);
|
||||
}
|
||||
else {
|
||||
let type;
|
||||
if (internals.isIsoDate(this._flags.format)) {
|
||||
type = 'isoDate';
|
||||
}
|
||||
else if (this._flags.timestamp) {
|
||||
type = `timestamp.${this._flags.timestamp}`;
|
||||
}
|
||||
else {
|
||||
type = 'base';
|
||||
}
|
||||
|
||||
result.errors = this.createError(`date.${type}`, { value }, state, options);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static toDate(value, format, timestamp, multiplier) {
|
||||
|
||||
if (value instanceof Date) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof value === 'string' ||
|
||||
(typeof value === 'number' && !isNaN(value) && isFinite(value))) {
|
||||
|
||||
const isIsoDate = format && internals.isIsoDate(format);
|
||||
if (!isIsoDate &&
|
||||
typeof value === 'string' &&
|
||||
/^[+-]?\d+(\.\d+)?$/.test(value)) {
|
||||
|
||||
value = parseFloat(value);
|
||||
}
|
||||
|
||||
let date;
|
||||
if (isIsoDate) {
|
||||
date = format.test(value) ? new Date(value.toString()) : internals.invalidDate;
|
||||
}
|
||||
else if (timestamp) {
|
||||
date = /^\s*$/.test(value) ? internals.invalidDate : new Date(value * multiplier);
|
||||
}
|
||||
else {
|
||||
date = new Date(value);
|
||||
}
|
||||
|
||||
if (!isNaN(date.getTime())) {
|
||||
return date;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
iso() {
|
||||
|
||||
if (this._flags.format === internals.isoDate) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.format = internals.isoDate;
|
||||
return obj;
|
||||
}
|
||||
|
||||
timestamp(type = 'javascript') {
|
||||
|
||||
const allowed = ['javascript', 'unix'];
|
||||
Hoek.assert(allowed.includes(type), '"type" must be one of "' + allowed.join('", "') + '"');
|
||||
|
||||
if (this._flags.timestamp === type) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.timestamp = type;
|
||||
obj._flags.multiplier = type === 'unix' ? 1000 : 1;
|
||||
return obj;
|
||||
}
|
||||
|
||||
_isIsoDate(value) {
|
||||
|
||||
return internals.isoDate.test(value);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
internals.compare = function (type, compare) {
|
||||
|
||||
return function (date) {
|
||||
|
||||
const isNow = date === 'now';
|
||||
const isRef = Ref.isRef(date);
|
||||
|
||||
if (!isNow && !isRef) {
|
||||
date = internals.Date.toDate(date);
|
||||
}
|
||||
|
||||
Hoek.assert(date, 'Invalid date format');
|
||||
|
||||
return this._test(type, date, function (value, state, options) {
|
||||
|
||||
let compareTo;
|
||||
if (isNow) {
|
||||
compareTo = Date.now();
|
||||
}
|
||||
else if (isRef) {
|
||||
const refValue = date(state.reference || state.parent, options);
|
||||
compareTo = internals.Date.toDate(refValue);
|
||||
|
||||
if (!compareTo) {
|
||||
return this.createError('date.ref', { ref: date, value: refValue }, state, options);
|
||||
}
|
||||
|
||||
compareTo = compareTo.getTime();
|
||||
}
|
||||
else {
|
||||
compareTo = date.getTime();
|
||||
}
|
||||
|
||||
if (compare(value.getTime(), compareTo)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('date.' + type, { limit: new Date(compareTo), value }, state, options);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
internals.Date.prototype.min = internals.compare('min', (value, date) => value >= date);
|
||||
internals.Date.prototype.max = internals.compare('max', (value, date) => value <= date);
|
||||
internals.Date.prototype.greater = internals.compare('greater', (value, date) => value > date);
|
||||
internals.Date.prototype.less = internals.compare('less', (value, date) => value < date);
|
||||
|
||||
|
||||
module.exports = new internals.Date();
|
87
web/node_modules/@hapi/joi/lib/types/func/index.js
generated
vendored
Executable file
87
web/node_modules/@hapi/joi/lib/types/func/index.js
generated
vendored
Executable file
|
@ -0,0 +1,87 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const ObjectType = require('../object');
|
||||
const Ref = require('../../ref');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
internals.Func = class extends ObjectType.constructor {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this._flags.func = true;
|
||||
}
|
||||
|
||||
arity(n) {
|
||||
|
||||
Hoek.assert(Number.isSafeInteger(n) && n >= 0, 'n must be a positive integer');
|
||||
|
||||
return this._test('arity', n, function (value, state, options) {
|
||||
|
||||
if (value.length === n) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('function.arity', { n }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
minArity(n) {
|
||||
|
||||
Hoek.assert(Number.isSafeInteger(n) && n > 0, 'n must be a strict positive integer');
|
||||
|
||||
return this._test('minArity', n, function (value, state, options) {
|
||||
|
||||
if (value.length >= n) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('function.minArity', { n }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
maxArity(n) {
|
||||
|
||||
Hoek.assert(Number.isSafeInteger(n) && n >= 0, 'n must be a positive integer');
|
||||
|
||||
return this._test('maxArity', n, function (value, state, options) {
|
||||
|
||||
if (value.length <= n) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('function.maxArity', { n }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
ref() {
|
||||
|
||||
return this._test('ref', null, function (value, state, options) {
|
||||
|
||||
if (Ref.isRef(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('function.ref', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
class() {
|
||||
|
||||
return this._test('class', null, function (value, state, options) {
|
||||
|
||||
if ((/^\s*class\s/).test(value.toString())) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('function.class', { value }, state, options);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = new internals.Func();
|
79
web/node_modules/@hapi/joi/lib/types/lazy/index.js
generated
vendored
Executable file
79
web/node_modules/@hapi/joi/lib/types/lazy/index.js
generated
vendored
Executable file
|
@ -0,0 +1,79 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Any = require('../any');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
internals.Lazy = class extends Any {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this._type = 'lazy';
|
||||
this._flags.once = true;
|
||||
this._cache = null;
|
||||
}
|
||||
|
||||
_init(fn, options) {
|
||||
|
||||
return this.set(fn, options);
|
||||
}
|
||||
|
||||
_base(value, state, options) {
|
||||
|
||||
let schema;
|
||||
if (this._cache) {
|
||||
schema = this._cache;
|
||||
}
|
||||
else {
|
||||
const result = { value };
|
||||
const lazy = this._flags.lazy;
|
||||
|
||||
if (!lazy) {
|
||||
result.errors = this.createError('lazy.base', null, state, options);
|
||||
return result;
|
||||
}
|
||||
|
||||
schema = lazy();
|
||||
|
||||
if (!(schema instanceof Any)) {
|
||||
result.errors = this.createError('lazy.schema', { schema }, state, options);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (this._flags.once) {
|
||||
this._cache = schema;
|
||||
}
|
||||
}
|
||||
|
||||
return schema._validate(value, state, options);
|
||||
}
|
||||
|
||||
set(fn, options) {
|
||||
|
||||
Hoek.assert(typeof fn === 'function', 'You must provide a function as first argument');
|
||||
Hoek.assert(options === undefined || (options && typeof options === 'object' && !Array.isArray(options)), `Options must be an object`);
|
||||
|
||||
if (options) {
|
||||
const unknownOptions = Object.keys(options).filter((key) => !['once'].includes(key));
|
||||
Hoek.assert(unknownOptions.length === 0, `Options contain unknown keys: ${unknownOptions}`);
|
||||
Hoek.assert(options.once === undefined || typeof options.once === 'boolean', 'Option "once" must be a boolean');
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.lazy = fn;
|
||||
|
||||
if (options && options.once !== obj._flags.once) {
|
||||
obj._flags.once = options.once;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
module.exports = new internals.Lazy();
|
245
web/node_modules/@hapi/joi/lib/types/number/index.js
generated
vendored
Executable file
245
web/node_modules/@hapi/joi/lib/types/number/index.js
generated
vendored
Executable file
|
@ -0,0 +1,245 @@
|
|||
'use strict';
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Any = require('../any');
|
||||
const Ref = require('../../ref');
|
||||
|
||||
|
||||
const internals = {
|
||||
precisionRx: /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/,
|
||||
normalizeExponent(str) {
|
||||
|
||||
return str
|
||||
.replace(/\.?0+e/, 'e')
|
||||
.replace(/e\+/, 'e')
|
||||
.replace(/^\+/, '')
|
||||
.replace(/^(-?)0+([1-9])/, '$1$2');
|
||||
},
|
||||
normalizeDecimal(str) {
|
||||
|
||||
str = str
|
||||
.replace(/^\+/, '')
|
||||
.replace(/\.0+$/, '')
|
||||
.replace(/^(-?)0+([1-9])/, '$1$2');
|
||||
|
||||
if (str.includes('.') && str.endsWith('0')) {
|
||||
str = str.replace(/0+$/, '');
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.Number = class extends Any {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this._type = 'number';
|
||||
this._flags.unsafe = false;
|
||||
this._invalids.add(Infinity);
|
||||
this._invalids.add(-Infinity);
|
||||
}
|
||||
|
||||
_base(value, state, options) {
|
||||
|
||||
const result = {
|
||||
errors: null,
|
||||
value
|
||||
};
|
||||
|
||||
if (typeof value === 'string' &&
|
||||
options.convert) {
|
||||
|
||||
const matches = value.match(/^\s*[+-]?\d+(?:\.\d+)?(?:e([+-]?\d+))?\s*$/i);
|
||||
if (matches) {
|
||||
|
||||
value = value.trim();
|
||||
result.value = parseFloat(value);
|
||||
|
||||
if (!this._flags.unsafe) {
|
||||
if (value.includes('e')) {
|
||||
if (internals.normalizeExponent(`${result.value / Math.pow(10, matches[1])}e${matches[1]}`) !== internals.normalizeExponent(value)) {
|
||||
result.errors = this.createError('number.unsafe', { value }, state, options);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (result.value.toString() !== internals.normalizeDecimal(value)) {
|
||||
result.errors = this.createError('number.unsafe', { value }, state, options);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const isNumber = typeof result.value === 'number' && !isNaN(result.value);
|
||||
|
||||
if (options.convert && 'precision' in this._flags && isNumber) {
|
||||
|
||||
// This is conceptually equivalent to using toFixed but it should be much faster
|
||||
const precision = Math.pow(10, this._flags.precision);
|
||||
result.value = Math.round(result.value * precision) / precision;
|
||||
}
|
||||
|
||||
if (isNumber) {
|
||||
if (!this._flags.unsafe &&
|
||||
(value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER)) {
|
||||
result.errors = this.createError('number.unsafe', { value }, state, options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.errors = this.createError('number.base', { value }, state, options);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
multiple(base) {
|
||||
|
||||
const isRef = Ref.isRef(base);
|
||||
|
||||
if (!isRef) {
|
||||
Hoek.assert(typeof base === 'number' && isFinite(base), 'multiple must be a number');
|
||||
Hoek.assert(base > 0, 'multiple must be greater than 0');
|
||||
}
|
||||
|
||||
return this._test('multiple', base, function (value, state, options) {
|
||||
|
||||
const divisor = isRef ? base(state.reference || state.parent, options) : base;
|
||||
|
||||
if (isRef && (typeof divisor !== 'number' || !isFinite(divisor))) {
|
||||
return this.createError('number.ref', { ref: base.key }, state, options);
|
||||
}
|
||||
|
||||
if (value % divisor === 0) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('number.multiple', { multiple: base, value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
integer() {
|
||||
|
||||
return this._test('integer', undefined, function (value, state, options) {
|
||||
|
||||
return Math.trunc(value) - value === 0 ? value : this.createError('number.integer', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
unsafe(enabled = true) {
|
||||
|
||||
Hoek.assert(typeof enabled === 'boolean', 'enabled must be a boolean');
|
||||
|
||||
if (this._flags.unsafe === enabled) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.unsafe = enabled;
|
||||
return obj;
|
||||
}
|
||||
|
||||
negative() {
|
||||
|
||||
return this._test('negative', undefined, function (value, state, options) {
|
||||
|
||||
if (value < 0) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('number.negative', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
positive() {
|
||||
|
||||
return this._test('positive', undefined, function (value, state, options) {
|
||||
|
||||
if (value > 0) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('number.positive', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
precision(limit) {
|
||||
|
||||
Hoek.assert(Number.isSafeInteger(limit), 'limit must be an integer');
|
||||
Hoek.assert(!('precision' in this._flags), 'precision already set');
|
||||
|
||||
const obj = this._test('precision', limit, function (value, state, options) {
|
||||
|
||||
const places = value.toString().match(internals.precisionRx);
|
||||
const decimals = Math.max((places[1] ? places[1].length : 0) - (places[2] ? parseInt(places[2], 10) : 0), 0);
|
||||
if (decimals <= limit) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('number.precision', { limit, value }, state, options);
|
||||
});
|
||||
|
||||
obj._flags.precision = limit;
|
||||
return obj;
|
||||
}
|
||||
|
||||
port() {
|
||||
|
||||
return this._test('port', undefined, function (value, state, options) {
|
||||
|
||||
if (!Number.isSafeInteger(value) || value < 0 || value > 65535) {
|
||||
return this.createError('number.port', { value }, state, options);
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
internals.compare = function (type, compare) {
|
||||
|
||||
return function (limit) {
|
||||
|
||||
const isRef = Ref.isRef(limit);
|
||||
const isNumber = typeof limit === 'number' && !isNaN(limit);
|
||||
|
||||
Hoek.assert(isNumber || isRef, 'limit must be a number or reference');
|
||||
|
||||
return this._test(type, limit, function (value, state, options) {
|
||||
|
||||
let compareTo;
|
||||
if (isRef) {
|
||||
compareTo = limit(state.reference || state.parent, options);
|
||||
|
||||
if (!(typeof compareTo === 'number' && !isNaN(compareTo))) {
|
||||
return this.createError('number.ref', { ref: limit.key }, state, options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
compareTo = limit;
|
||||
}
|
||||
|
||||
if (compare(value, compareTo)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('number.' + type, { limit: compareTo, value }, state, options);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
internals.Number.prototype.min = internals.compare('min', (value, limit) => value >= limit);
|
||||
internals.Number.prototype.max = internals.compare('max', (value, limit) => value <= limit);
|
||||
internals.Number.prototype.greater = internals.compare('greater', (value, limit) => value > limit);
|
||||
internals.Number.prototype.less = internals.compare('less', (value, limit) => value < limit);
|
||||
|
||||
|
||||
module.exports = new internals.Number();
|
952
web/node_modules/@hapi/joi/lib/types/object/index.js
generated
vendored
Executable file
952
web/node_modules/@hapi/joi/lib/types/object/index.js
generated
vendored
Executable file
|
@ -0,0 +1,952 @@
|
|||
'use strict';
|
||||
|
||||
const Bourne = require('@hapi/bourne');
|
||||
const Hoek = require('@hapi/hoek');
|
||||
const Topo = require('@hapi/topo');
|
||||
|
||||
const Any = require('../any');
|
||||
const Errors = require('../../errors');
|
||||
const Cast = require('../../cast');
|
||||
const State = require('../state');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
internals.Object = class extends Any {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this._type = 'object';
|
||||
this._inner.children = null;
|
||||
this._inner.renames = [];
|
||||
this._inner.dependencies = [];
|
||||
this._inner.patterns = [];
|
||||
}
|
||||
|
||||
_init(...args) {
|
||||
|
||||
return args.length ? this.keys(...args) : this;
|
||||
}
|
||||
|
||||
_base(value, state, options) {
|
||||
|
||||
let target = value;
|
||||
const errors = [];
|
||||
const finish = () => {
|
||||
|
||||
return {
|
||||
value: target,
|
||||
errors: errors.length ? errors : null
|
||||
};
|
||||
};
|
||||
|
||||
if (typeof value === 'string' &&
|
||||
options.convert) {
|
||||
|
||||
if (value.length > 1 &&
|
||||
(value[0] === '{' || /^\s*\{/.test(value))) {
|
||||
|
||||
try {
|
||||
value = Bourne.parse(value);
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
}
|
||||
|
||||
const type = this._flags.func ? 'function' : 'object';
|
||||
if (!value ||
|
||||
typeof value !== type ||
|
||||
Array.isArray(value)) {
|
||||
|
||||
errors.push(this.createError(type + '.base', { value }, state, options));
|
||||
return finish();
|
||||
}
|
||||
|
||||
// Skip if there are no other rules to test
|
||||
|
||||
if (!this._inner.renames.length &&
|
||||
!this._inner.dependencies.length &&
|
||||
!this._inner.children && // null allows any keys
|
||||
!this._inner.patterns.length) {
|
||||
|
||||
target = value;
|
||||
return finish();
|
||||
}
|
||||
|
||||
// Ensure target is a local copy (parsed) or shallow copy
|
||||
|
||||
if (target === value) {
|
||||
if (type === 'object') {
|
||||
target = Object.create(Object.getPrototypeOf(value));
|
||||
}
|
||||
else {
|
||||
target = function (...args) {
|
||||
|
||||
return value.apply(this, args);
|
||||
};
|
||||
|
||||
target.prototype = Hoek.clone(value.prototype);
|
||||
}
|
||||
|
||||
const valueKeys = Object.keys(value);
|
||||
for (let i = 0; i < valueKeys.length; ++i) {
|
||||
target[valueKeys[i]] = value[valueKeys[i]];
|
||||
}
|
||||
}
|
||||
else {
|
||||
target = value;
|
||||
}
|
||||
|
||||
// Rename keys
|
||||
|
||||
const renamed = {};
|
||||
for (let i = 0; i < this._inner.renames.length; ++i) {
|
||||
const rename = this._inner.renames[i];
|
||||
|
||||
if (rename.isRegExp) {
|
||||
const targetKeys = Object.keys(target);
|
||||
const matchedTargetKeys = [];
|
||||
|
||||
for (let j = 0; j < targetKeys.length; ++j) {
|
||||
if (rename.from.test(targetKeys[j])) {
|
||||
matchedTargetKeys.push(targetKeys[j]);
|
||||
}
|
||||
}
|
||||
|
||||
const allUndefined = matchedTargetKeys.every((key) => target[key] === undefined);
|
||||
if (rename.options.ignoreUndefined && allUndefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!rename.options.multiple &&
|
||||
renamed[rename.to]) {
|
||||
|
||||
errors.push(this.createError('object.rename.regex.multiple', { from: matchedTargetKeys, to: rename.to }, state, options));
|
||||
if (options.abortEarly) {
|
||||
return finish();
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(target, rename.to) &&
|
||||
!rename.options.override &&
|
||||
!renamed[rename.to]) {
|
||||
|
||||
errors.push(this.createError('object.rename.regex.override', { from: matchedTargetKeys, to: rename.to }, state, options));
|
||||
if (options.abortEarly) {
|
||||
return finish();
|
||||
}
|
||||
}
|
||||
|
||||
if (allUndefined) {
|
||||
delete target[rename.to];
|
||||
}
|
||||
else {
|
||||
target[rename.to] = target[matchedTargetKeys[matchedTargetKeys.length - 1]];
|
||||
}
|
||||
|
||||
renamed[rename.to] = true;
|
||||
|
||||
if (!rename.options.alias) {
|
||||
for (let j = 0; j < matchedTargetKeys.length; ++j) {
|
||||
delete target[matchedTargetKeys[j]];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rename.options.ignoreUndefined && target[rename.from] === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!rename.options.multiple &&
|
||||
renamed[rename.to]) {
|
||||
|
||||
errors.push(this.createError('object.rename.multiple', { from: rename.from, to: rename.to }, state, options));
|
||||
if (options.abortEarly) {
|
||||
return finish();
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(target, rename.to) &&
|
||||
!rename.options.override &&
|
||||
!renamed[rename.to]) {
|
||||
|
||||
errors.push(this.createError('object.rename.override', { from: rename.from, to: rename.to }, state, options));
|
||||
if (options.abortEarly) {
|
||||
return finish();
|
||||
}
|
||||
}
|
||||
|
||||
if (target[rename.from] === undefined) {
|
||||
delete target[rename.to];
|
||||
}
|
||||
else {
|
||||
target[rename.to] = target[rename.from];
|
||||
}
|
||||
|
||||
renamed[rename.to] = true;
|
||||
|
||||
if (!rename.options.alias) {
|
||||
delete target[rename.from];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate schema
|
||||
|
||||
if (!this._inner.children && // null allows any keys
|
||||
!this._inner.patterns.length &&
|
||||
!this._inner.dependencies.length) {
|
||||
|
||||
return finish();
|
||||
}
|
||||
|
||||
const unprocessed = new Set(Object.keys(target));
|
||||
|
||||
if (this._inner.children) {
|
||||
const stripProps = [];
|
||||
|
||||
for (let i = 0; i < this._inner.children.length; ++i) {
|
||||
const child = this._inner.children[i];
|
||||
const key = child.key;
|
||||
const item = target[key];
|
||||
|
||||
unprocessed.delete(key);
|
||||
|
||||
const localState = new State(key, [...state.path, key], target, state.reference);
|
||||
const result = child.schema._validate(item, localState, options);
|
||||
if (result.errors) {
|
||||
errors.push(this.createError('object.child', { key, child: child.schema._getLabel(key), reason: result.errors }, localState, options));
|
||||
|
||||
if (options.abortEarly) {
|
||||
return finish();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (child.schema._flags.strip || (result.value === undefined && result.value !== item)) {
|
||||
stripProps.push(key);
|
||||
target[key] = result.finalValue;
|
||||
}
|
||||
else if (result.value !== undefined) {
|
||||
target[key] = result.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < stripProps.length; ++i) {
|
||||
delete target[stripProps[i]];
|
||||
}
|
||||
}
|
||||
|
||||
// Unknown keys
|
||||
|
||||
if (unprocessed.size && this._inner.patterns.length) {
|
||||
|
||||
for (const key of unprocessed) {
|
||||
const localState = new State(key, [...state.path, key], target, state.reference);
|
||||
const item = target[key];
|
||||
|
||||
for (let i = 0; i < this._inner.patterns.length; ++i) {
|
||||
const pattern = this._inner.patterns[i];
|
||||
|
||||
if (pattern.regex ?
|
||||
pattern.regex.test(key) :
|
||||
!pattern.schema._validate(key, state, { ...options, abortEarly:true }).errors) {
|
||||
|
||||
unprocessed.delete(key);
|
||||
|
||||
const result = pattern.rule._validate(item, localState, options);
|
||||
if (result.errors) {
|
||||
errors.push(this.createError('object.child', {
|
||||
key,
|
||||
child: pattern.rule._getLabel(key),
|
||||
reason: result.errors
|
||||
}, localState, options));
|
||||
|
||||
if (options.abortEarly) {
|
||||
return finish();
|
||||
}
|
||||
}
|
||||
|
||||
target[key] = result.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (unprocessed.size && (this._inner.children || this._inner.patterns.length)) {
|
||||
if ((options.stripUnknown && this._flags.allowUnknown !== true) ||
|
||||
options.skipFunctions) {
|
||||
|
||||
const stripUnknown = options.stripUnknown
|
||||
? (options.stripUnknown === true ? true : !!options.stripUnknown.objects)
|
||||
: false;
|
||||
|
||||
|
||||
for (const key of unprocessed) {
|
||||
if (stripUnknown) {
|
||||
delete target[key];
|
||||
unprocessed.delete(key);
|
||||
}
|
||||
else if (typeof target[key] === 'function') {
|
||||
unprocessed.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((this._flags.allowUnknown !== undefined ? !this._flags.allowUnknown : !options.allowUnknown)) {
|
||||
|
||||
for (const unprocessedKey of unprocessed) {
|
||||
errors.push(this.createError('object.allowUnknown', { child: unprocessedKey, value: target[unprocessedKey] }, {
|
||||
key: unprocessedKey,
|
||||
path: [...state.path, unprocessedKey]
|
||||
}, options, {}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate dependencies
|
||||
|
||||
for (let i = 0; i < this._inner.dependencies.length; ++i) {
|
||||
const dep = this._inner.dependencies[i];
|
||||
const hasKey = dep.key !== null;
|
||||
const splitKey = hasKey && dep.key.split('.');
|
||||
const localState = hasKey ? new State(splitKey[splitKey.length - 1], [...state.path, ...splitKey]) : new State(null, state.path);
|
||||
const err = internals[dep.type].call(this, dep.key, hasKey && Hoek.reach(target, dep.key, { functions: true }), dep.peers, target, localState, options);
|
||||
if (err instanceof Errors.Err) {
|
||||
errors.push(err);
|
||||
if (options.abortEarly) {
|
||||
return finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return finish();
|
||||
}
|
||||
|
||||
keys(schema) {
|
||||
|
||||
Hoek.assert(schema === null || schema === undefined || typeof schema === 'object', 'Object schema must be a valid object');
|
||||
Hoek.assert(!schema || !(schema instanceof Any), 'Object schema cannot be a joi schema');
|
||||
|
||||
const obj = this.clone();
|
||||
|
||||
if (!schema) {
|
||||
obj._inner.children = null;
|
||||
return obj;
|
||||
}
|
||||
|
||||
const children = Object.keys(schema);
|
||||
|
||||
if (!children.length) {
|
||||
obj._inner.children = [];
|
||||
return obj;
|
||||
}
|
||||
|
||||
const topo = new Topo();
|
||||
if (obj._inner.children) {
|
||||
for (let i = 0; i < obj._inner.children.length; ++i) {
|
||||
const child = obj._inner.children[i];
|
||||
|
||||
// Only add the key if we are not going to replace it later
|
||||
if (!children.includes(child.key)) {
|
||||
topo.add(child, { after: child._refs, group: child.key });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < children.length; ++i) {
|
||||
const key = children[i];
|
||||
const child = schema[key];
|
||||
try {
|
||||
const cast = Cast.schema(this._currentJoi, child);
|
||||
topo.add({ key, schema: cast }, { after: cast._refs, group: key });
|
||||
}
|
||||
catch (castErr) {
|
||||
if (castErr.hasOwnProperty('path')) {
|
||||
castErr.path = key + '.' + castErr.path;
|
||||
}
|
||||
else {
|
||||
castErr.path = key;
|
||||
}
|
||||
|
||||
throw castErr;
|
||||
}
|
||||
}
|
||||
|
||||
obj._inner.children = topo.nodes;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
append(schema) {
|
||||
// Skip any changes
|
||||
if (schema === null || schema === undefined || Object.keys(schema).length === 0) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return this.keys(schema);
|
||||
}
|
||||
|
||||
unknown(allow) {
|
||||
|
||||
const value = allow !== false;
|
||||
|
||||
if (this._flags.allowUnknown === value) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.allowUnknown = value;
|
||||
return obj;
|
||||
}
|
||||
|
||||
length(limit) {
|
||||
|
||||
Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');
|
||||
|
||||
return this._test('length', limit, function (value, state, options) {
|
||||
|
||||
if (Object.keys(value).length === limit) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('object.length', { limit, value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
min(limit) {
|
||||
|
||||
Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');
|
||||
|
||||
return this._test('min', limit, function (value, state, options) {
|
||||
|
||||
if (Object.keys(value).length >= limit) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('object.min', { limit, value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
max(limit) {
|
||||
|
||||
Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');
|
||||
|
||||
return this._test('max', limit, function (value, state, options) {
|
||||
|
||||
if (Object.keys(value).length <= limit) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('object.max', { limit, value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
pattern(pattern, schema) {
|
||||
|
||||
const isRegExp = pattern instanceof RegExp;
|
||||
Hoek.assert(isRegExp || pattern instanceof Any, 'pattern must be a regex or schema');
|
||||
Hoek.assert(schema !== undefined, 'Invalid rule');
|
||||
|
||||
if (isRegExp) {
|
||||
Hoek.assert(!pattern.flags.includes('g') && !pattern.flags.includes('y'), 'pattern should not use global or sticky mode');
|
||||
}
|
||||
|
||||
try {
|
||||
schema = Cast.schema(this._currentJoi, schema);
|
||||
}
|
||||
catch (castErr) {
|
||||
if (castErr.hasOwnProperty('path')) {
|
||||
castErr.message = `${castErr.message}(${castErr.path})`;
|
||||
}
|
||||
|
||||
throw castErr;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
if (isRegExp) {
|
||||
obj._inner.patterns.push({ regex: pattern, rule: schema });
|
||||
}
|
||||
else {
|
||||
obj._inner.patterns.push({ schema: pattern, rule: schema });
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
schema() {
|
||||
|
||||
return this._test('schema', null, function (value, state, options) {
|
||||
|
||||
if (value instanceof Any) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('object.schema', null, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
with(key, peers) {
|
||||
|
||||
Hoek.assert(arguments.length === 2, 'Invalid number of arguments, expected 2.');
|
||||
|
||||
return this._dependency('with', key, peers);
|
||||
}
|
||||
|
||||
without(key, peers) {
|
||||
|
||||
Hoek.assert(arguments.length === 2, 'Invalid number of arguments, expected 2.');
|
||||
|
||||
return this._dependency('without', key, peers);
|
||||
}
|
||||
|
||||
xor(...peers) {
|
||||
|
||||
peers = Hoek.flatten(peers);
|
||||
return this._dependency('xor', null, peers);
|
||||
}
|
||||
|
||||
oxor(...peers) {
|
||||
|
||||
return this._dependency('oxor', null, peers);
|
||||
}
|
||||
|
||||
or(...peers) {
|
||||
|
||||
peers = Hoek.flatten(peers);
|
||||
return this._dependency('or', null, peers);
|
||||
}
|
||||
|
||||
and(...peers) {
|
||||
|
||||
peers = Hoek.flatten(peers);
|
||||
return this._dependency('and', null, peers);
|
||||
}
|
||||
|
||||
nand(...peers) {
|
||||
|
||||
peers = Hoek.flatten(peers);
|
||||
return this._dependency('nand', null, peers);
|
||||
}
|
||||
|
||||
requiredKeys(...children) {
|
||||
|
||||
children = Hoek.flatten(children);
|
||||
return this.applyFunctionToChildren(children, 'required');
|
||||
}
|
||||
|
||||
optionalKeys(...children) {
|
||||
|
||||
children = Hoek.flatten(children);
|
||||
return this.applyFunctionToChildren(children, 'optional');
|
||||
}
|
||||
|
||||
forbiddenKeys(...children) {
|
||||
|
||||
children = Hoek.flatten(children);
|
||||
return this.applyFunctionToChildren(children, 'forbidden');
|
||||
}
|
||||
|
||||
rename(from, to, options) {
|
||||
|
||||
Hoek.assert(typeof from === 'string' || from instanceof RegExp, 'Rename missing the from argument');
|
||||
Hoek.assert(typeof to === 'string', 'Rename missing the to argument');
|
||||
Hoek.assert(to !== from, 'Cannot rename key to same name:', from);
|
||||
|
||||
for (let i = 0; i < this._inner.renames.length; ++i) {
|
||||
Hoek.assert(this._inner.renames[i].from !== from, 'Cannot rename the same key multiple times');
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
|
||||
obj._inner.renames.push({
|
||||
from,
|
||||
to,
|
||||
options: Hoek.applyToDefaults(internals.renameDefaults, options || {}),
|
||||
isRegExp: from instanceof RegExp
|
||||
});
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
applyFunctionToChildren(children, fn, args = [], root) {
|
||||
|
||||
children = [].concat(children);
|
||||
Hoek.assert(children.length > 0, 'expected at least one children');
|
||||
|
||||
const groupedChildren = internals.groupChildren(children);
|
||||
let obj;
|
||||
|
||||
if ('' in groupedChildren) {
|
||||
obj = this[fn](...args);
|
||||
delete groupedChildren[''];
|
||||
}
|
||||
else {
|
||||
obj = this.clone();
|
||||
}
|
||||
|
||||
if (obj._inner.children) {
|
||||
root = root ? (root + '.') : '';
|
||||
|
||||
for (let i = 0; i < obj._inner.children.length; ++i) {
|
||||
const child = obj._inner.children[i];
|
||||
const group = groupedChildren[child.key];
|
||||
|
||||
if (group) {
|
||||
obj._inner.children[i] = {
|
||||
key: child.key,
|
||||
_refs: child._refs,
|
||||
schema: child.schema.applyFunctionToChildren(group, fn, args, root + child.key)
|
||||
};
|
||||
|
||||
delete groupedChildren[child.key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const remaining = Object.keys(groupedChildren);
|
||||
Hoek.assert(remaining.length === 0, 'unknown key(s)', remaining.join(', '));
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
_dependency(type, key, peers) {
|
||||
|
||||
peers = [].concat(peers);
|
||||
for (let i = 0; i < peers.length; ++i) {
|
||||
Hoek.assert(typeof peers[i] === 'string', type, 'peers must be a string or array of strings');
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._inner.dependencies.push({ type, key, peers });
|
||||
return obj;
|
||||
}
|
||||
|
||||
describe(shallow) {
|
||||
|
||||
const description = super.describe();
|
||||
|
||||
if (description.rules) {
|
||||
for (let i = 0; i < description.rules.length; ++i) {
|
||||
const rule = description.rules[i];
|
||||
// Coverage off for future-proof descriptions, only object().assert() is use right now
|
||||
if (/* $lab:coverage:off$ */rule.arg &&
|
||||
typeof rule.arg === 'object' &&
|
||||
rule.arg.schema &&
|
||||
rule.arg.ref /* $lab:coverage:on$ */) {
|
||||
rule.arg = {
|
||||
schema: rule.arg.schema.describe(),
|
||||
ref: rule.arg.ref.toString()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this._inner.children &&
|
||||
!shallow) {
|
||||
|
||||
description.children = {};
|
||||
for (let i = 0; i < this._inner.children.length; ++i) {
|
||||
const child = this._inner.children[i];
|
||||
description.children[child.key] = child.schema.describe();
|
||||
}
|
||||
}
|
||||
|
||||
if (this._inner.dependencies.length) {
|
||||
description.dependencies = Hoek.clone(this._inner.dependencies);
|
||||
}
|
||||
|
||||
if (this._inner.patterns.length) {
|
||||
description.patterns = [];
|
||||
|
||||
for (let i = 0; i < this._inner.patterns.length; ++i) {
|
||||
const pattern = this._inner.patterns[i];
|
||||
if (pattern.regex) {
|
||||
description.patterns.push({ regex: pattern.regex.toString(), rule: pattern.rule.describe() });
|
||||
}
|
||||
else {
|
||||
description.patterns.push({ schema: pattern.schema.describe(), rule: pattern.rule.describe() });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this._inner.renames.length > 0) {
|
||||
description.renames = Hoek.clone(this._inner.renames);
|
||||
}
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
assert(ref, schema, message) {
|
||||
|
||||
ref = Cast.ref(ref);
|
||||
Hoek.assert(ref.isContext || ref.depth > 1, 'Cannot use assertions for root level references - use direct key rules instead');
|
||||
message = message || 'pass the assertion test';
|
||||
Hoek.assert(typeof message === 'string', 'Message must be a string');
|
||||
|
||||
try {
|
||||
schema = Cast.schema(this._currentJoi, schema);
|
||||
}
|
||||
catch (castErr) {
|
||||
if (castErr.hasOwnProperty('path')) {
|
||||
castErr.message = `${castErr.message}(${castErr.path})`;
|
||||
}
|
||||
|
||||
throw castErr;
|
||||
}
|
||||
|
||||
const key = ref.path[ref.path.length - 1];
|
||||
const path = ref.path.join('.');
|
||||
|
||||
return this._test('assert', { schema, ref }, function (value, state, options) {
|
||||
|
||||
const result = schema._validate(ref(value), null, options, value);
|
||||
if (!result.errors) {
|
||||
return value;
|
||||
}
|
||||
|
||||
const localState = new State(key, ref.path, state.parent, state.reference);
|
||||
return this.createError('object.assert', { ref: path, message }, localState, options);
|
||||
});
|
||||
}
|
||||
|
||||
type(constructor, name = constructor.name) {
|
||||
|
||||
Hoek.assert(typeof constructor === 'function', 'type must be a constructor function');
|
||||
const typeData = {
|
||||
name,
|
||||
ctor: constructor
|
||||
};
|
||||
|
||||
return this._test('type', typeData, function (value, state, options) {
|
||||
|
||||
if (value instanceof constructor) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('object.type', { type: typeData.name, value }, state, options);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.renameDefaults = {
|
||||
alias: false, // Keep old value in place
|
||||
multiple: false, // Allow renaming multiple keys into the same target
|
||||
override: false // Overrides an existing key
|
||||
};
|
||||
|
||||
|
||||
internals.groupChildren = function (children) {
|
||||
|
||||
children.sort();
|
||||
|
||||
const grouped = {};
|
||||
|
||||
for (let i = 0; i < children.length; ++i) {
|
||||
const child = children[i];
|
||||
Hoek.assert(typeof child === 'string', 'children must be strings');
|
||||
const group = child.split('.')[0];
|
||||
const childGroup = grouped[group] = (grouped[group] || []);
|
||||
childGroup.push(child.substring(group.length + 1));
|
||||
}
|
||||
|
||||
return grouped;
|
||||
};
|
||||
|
||||
|
||||
internals.keysToLabels = function (schema, keys) {
|
||||
|
||||
const children = schema._inner.children;
|
||||
|
||||
if (!children) {
|
||||
return keys;
|
||||
}
|
||||
|
||||
const findLabel = function (key) {
|
||||
|
||||
const matchingChild = schema._currentJoi.reach(schema, key);
|
||||
return matchingChild ? matchingChild._getLabel(key) : key;
|
||||
};
|
||||
|
||||
if (Array.isArray(keys)) {
|
||||
return keys.map(findLabel);
|
||||
}
|
||||
|
||||
return findLabel(keys);
|
||||
};
|
||||
|
||||
|
||||
internals.with = function (key, value, peers, parent, state, options) {
|
||||
|
||||
if (value === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < peers.length; ++i) {
|
||||
|
||||
const peer = peers[i];
|
||||
const keysExist = Hoek.reach(parent, peer, { functions: true });
|
||||
if (keysExist === undefined) {
|
||||
|
||||
return this.createError('object.with', {
|
||||
main: key,
|
||||
mainWithLabel: internals.keysToLabels(this, key),
|
||||
peer,
|
||||
peerWithLabel: internals.keysToLabels(this, peer)
|
||||
}, state, options);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.without = function (key, value, peers, parent, state, options) {
|
||||
|
||||
if (value === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < peers.length; ++i) {
|
||||
const peer = peers[i];
|
||||
const keysExist = Hoek.reach(parent, peer, { functions: true });
|
||||
if (keysExist !== undefined) {
|
||||
|
||||
return this.createError('object.without', {
|
||||
main: key,
|
||||
mainWithLabel: internals.keysToLabels(this, key),
|
||||
peer,
|
||||
peerWithLabel: internals.keysToLabels(this, peer)
|
||||
}, state, options);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.xor = function (key, value, peers, parent, state, options) {
|
||||
|
||||
const present = [];
|
||||
for (let i = 0; i < peers.length; ++i) {
|
||||
const peer = peers[i];
|
||||
const keysExist = Hoek.reach(parent, peer, { functions: true });
|
||||
if (keysExist !== undefined) {
|
||||
present.push(peer);
|
||||
}
|
||||
}
|
||||
|
||||
if (present.length === 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const context = { peers, peersWithLabels: internals.keysToLabels(this, peers) };
|
||||
|
||||
if (present.length === 0) {
|
||||
return this.createError('object.missing', context, state, options);
|
||||
}
|
||||
|
||||
context.present = present;
|
||||
context.presentWithLabels = internals.keysToLabels(this, present);
|
||||
|
||||
return this.createError('object.xor', context, state, options);
|
||||
};
|
||||
|
||||
|
||||
internals.oxor = function (key, value, peers, parent, state, options) {
|
||||
|
||||
const present = [];
|
||||
for (let i = 0; i < peers.length; ++i) {
|
||||
const peer = peers[i];
|
||||
const keysExist = Hoek.reach(parent, peer, { functions: true });
|
||||
if (keysExist !== undefined) {
|
||||
present.push(peer);
|
||||
}
|
||||
}
|
||||
|
||||
if (!present.length ||
|
||||
present.length === 1) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const context = { peers, peersWithLabels: internals.keysToLabels(this, peers) };
|
||||
context.present = present;
|
||||
context.presentWithLabels = internals.keysToLabels(this, present);
|
||||
|
||||
return this.createError('object.oxor', context, state, options);
|
||||
};
|
||||
|
||||
|
||||
internals.or = function (key, value, peers, parent, state, options) {
|
||||
|
||||
for (let i = 0; i < peers.length; ++i) {
|
||||
const peer = peers[i];
|
||||
const keysExist = Hoek.reach(parent, peer, { functions: true });
|
||||
if (keysExist !== undefined) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return this.createError('object.missing', {
|
||||
peers,
|
||||
peersWithLabels: internals.keysToLabels(this, peers)
|
||||
}, state, options);
|
||||
};
|
||||
|
||||
|
||||
internals.and = function (key, value, peers, parent, state, options) {
|
||||
|
||||
const missing = [];
|
||||
const present = [];
|
||||
const count = peers.length;
|
||||
for (let i = 0; i < count; ++i) {
|
||||
const peer = peers[i];
|
||||
const keysExist = Hoek.reach(parent, peer, { functions: true });
|
||||
if (keysExist === undefined) {
|
||||
|
||||
missing.push(peer);
|
||||
}
|
||||
else {
|
||||
present.push(peer);
|
||||
}
|
||||
}
|
||||
|
||||
const aon = (missing.length === count || present.length === count);
|
||||
|
||||
if (!aon) {
|
||||
|
||||
return this.createError('object.and', {
|
||||
present,
|
||||
presentWithLabels: internals.keysToLabels(this, present),
|
||||
missing,
|
||||
missingWithLabels: internals.keysToLabels(this, missing)
|
||||
}, state, options);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.nand = function (key, value, peers, parent, state, options) {
|
||||
|
||||
const present = [];
|
||||
for (let i = 0; i < peers.length; ++i) {
|
||||
const peer = peers[i];
|
||||
const keysExist = Hoek.reach(parent, peer, { functions: true });
|
||||
if (keysExist !== undefined) {
|
||||
|
||||
present.push(peer);
|
||||
}
|
||||
}
|
||||
|
||||
const main = peers[0];
|
||||
const values = peers.slice(1);
|
||||
const allPresent = (present.length === peers.length);
|
||||
return allPresent ? this.createError('object.nand', {
|
||||
main,
|
||||
mainWithLabel: internals.keysToLabels(this, main),
|
||||
peers: values,
|
||||
peersWithLabels: internals.keysToLabels(this, values)
|
||||
}, state, options) : null;
|
||||
};
|
||||
|
||||
|
||||
module.exports = new internals.Object();
|
14
web/node_modules/@hapi/joi/lib/types/state.js
generated
vendored
Executable file
14
web/node_modules/@hapi/joi/lib/types/state.js
generated
vendored
Executable file
|
@ -0,0 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
module.exports = class {
|
||||
constructor(key, path, parent, reference) {
|
||||
|
||||
this.key = key;
|
||||
this.path = path;
|
||||
this.parent = parent;
|
||||
this.reference = reference;
|
||||
}
|
||||
};
|
724
web/node_modules/@hapi/joi/lib/types/string/index.js
generated
vendored
Executable file
724
web/node_modules/@hapi/joi/lib/types/string/index.js
generated
vendored
Executable file
|
@ -0,0 +1,724 @@
|
|||
'use strict';
|
||||
|
||||
const Net = require('net');
|
||||
|
||||
const Address = require('@hapi/address');
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Any = require('../any');
|
||||
const Ref = require('../../ref');
|
||||
const JoiDate = require('../date');
|
||||
|
||||
const Uri = require('./uri');
|
||||
const Ip = require('./ip');
|
||||
|
||||
|
||||
const internals = {
|
||||
uriRegex: Uri.createUriRegex(),
|
||||
ipRegex: Ip.createIpRegex(['ipv4', 'ipv6', 'ipvfuture'], 'optional'),
|
||||
guidBrackets: {
|
||||
'{': '}', '[': ']', '(': ')', '': ''
|
||||
},
|
||||
guidVersions: {
|
||||
uuidv1: '1',
|
||||
uuidv2: '2',
|
||||
uuidv3: '3',
|
||||
uuidv4: '4',
|
||||
uuidv5: '5'
|
||||
},
|
||||
cidrPresences: ['required', 'optional', 'forbidden'],
|
||||
normalizationForms: ['NFC', 'NFD', 'NFKC', 'NFKD']
|
||||
};
|
||||
|
||||
|
||||
internals.String = class extends Any {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this._type = 'string';
|
||||
this._invalids.add('');
|
||||
}
|
||||
|
||||
_base(value, state, options) {
|
||||
|
||||
if (typeof value === 'string' &&
|
||||
options.convert) {
|
||||
|
||||
if (this._flags.normalize) {
|
||||
value = value.normalize(this._flags.normalize);
|
||||
}
|
||||
|
||||
if (this._flags.case) {
|
||||
value = (this._flags.case === 'upper' ? value.toLocaleUpperCase() : value.toLocaleLowerCase());
|
||||
}
|
||||
|
||||
if (this._flags.trim) {
|
||||
value = value.trim();
|
||||
}
|
||||
|
||||
if (this._inner.replacements) {
|
||||
|
||||
for (let i = 0; i < this._inner.replacements.length; ++i) {
|
||||
const replacement = this._inner.replacements[i];
|
||||
value = value.replace(replacement.pattern, replacement.replacement);
|
||||
}
|
||||
}
|
||||
|
||||
if (this._flags.truncate) {
|
||||
for (let i = 0; i < this._tests.length; ++i) {
|
||||
const test = this._tests[i];
|
||||
if (test.name === 'max') {
|
||||
value = value.slice(0, test.arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this._flags.byteAligned && value.length % 2 !== 0) {
|
||||
value = `0${value}`;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
value,
|
||||
errors: (typeof value === 'string') ? null : this.createError('string.base', { value }, state, options)
|
||||
};
|
||||
}
|
||||
|
||||
insensitive() {
|
||||
|
||||
if (this._flags.insensitive) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.insensitive = true;
|
||||
return obj;
|
||||
}
|
||||
|
||||
creditCard() {
|
||||
|
||||
return this._test('creditCard', undefined, function (value, state, options) {
|
||||
|
||||
let i = value.length;
|
||||
let sum = 0;
|
||||
let mul = 1;
|
||||
|
||||
while (i--) {
|
||||
const char = value.charAt(i) * mul;
|
||||
sum = sum + (char - (char > 9) * 9);
|
||||
mul = mul ^ 3;
|
||||
}
|
||||
|
||||
const check = (sum % 10 === 0) && (sum > 0);
|
||||
return check ? value : this.createError('string.creditCard', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
regex(pattern, patternOptions) {
|
||||
|
||||
Hoek.assert(pattern instanceof RegExp, 'pattern must be a RegExp');
|
||||
Hoek.assert(!pattern.flags.includes('g') && !pattern.flags.includes('y'), 'pattern should not use global or sticky mode');
|
||||
|
||||
const patternObject = { pattern };
|
||||
|
||||
if (typeof patternOptions === 'string') {
|
||||
patternObject.name = patternOptions;
|
||||
}
|
||||
else if (typeof patternOptions === 'object') {
|
||||
patternObject.invert = !!patternOptions.invert;
|
||||
|
||||
if (patternOptions.name) {
|
||||
patternObject.name = patternOptions.name;
|
||||
}
|
||||
}
|
||||
|
||||
const errorCode = ['string.regex', patternObject.invert ? '.invert' : '', patternObject.name ? '.name' : '.base'].join('');
|
||||
|
||||
return this._test('regex', patternObject, function (value, state, options) {
|
||||
|
||||
const patternMatch = patternObject.pattern.test(value);
|
||||
|
||||
if (patternMatch ^ patternObject.invert) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError(errorCode, { name: patternObject.name, pattern: patternObject.pattern, value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
alphanum() {
|
||||
|
||||
return this._test('alphanum', undefined, function (value, state, options) {
|
||||
|
||||
if (/^[a-zA-Z0-9]+$/.test(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('string.alphanum', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
token() {
|
||||
|
||||
return this._test('token', undefined, function (value, state, options) {
|
||||
|
||||
if (/^\w+$/.test(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('string.token', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
email(validationOptions) {
|
||||
|
||||
if (validationOptions) {
|
||||
Hoek.assert(typeof validationOptions === 'object', 'email options must be an object');
|
||||
|
||||
// Migration validation for unsupported options
|
||||
|
||||
Hoek.assert(validationOptions.checkDNS === undefined, 'checkDNS option is not supported');
|
||||
Hoek.assert(validationOptions.errorLevel === undefined, 'errorLevel option is not supported');
|
||||
Hoek.assert(validationOptions.minDomainAtoms === undefined, 'minDomainAtoms option is not supported, use minDomainSegments instead');
|
||||
Hoek.assert(validationOptions.tldBlacklist === undefined, 'tldBlacklist option is not supported, use tlds.deny instead');
|
||||
Hoek.assert(validationOptions.tldWhitelist === undefined, 'tldWhitelist option is not supported, use tlds.allow instead');
|
||||
|
||||
// Validate options
|
||||
|
||||
if (validationOptions.tlds &&
|
||||
typeof validationOptions.tlds === 'object') {
|
||||
|
||||
Hoek.assert(validationOptions.tlds.allow === undefined ||
|
||||
validationOptions.tlds.allow === false ||
|
||||
validationOptions.tlds.allow === true ||
|
||||
Array.isArray(validationOptions.tlds.allow) ||
|
||||
validationOptions.tlds.allow instanceof Set, 'tlds.allow must be an array, Set, or boolean');
|
||||
|
||||
Hoek.assert(validationOptions.tlds.deny === undefined ||
|
||||
Array.isArray(validationOptions.tlds.deny) ||
|
||||
validationOptions.tlds.deny instanceof Set, 'tlds.deny must be an array or Set');
|
||||
|
||||
const normalizeTable = (table) => {
|
||||
|
||||
if (table === undefined ||
|
||||
typeof table === 'boolean' ||
|
||||
table instanceof Set) {
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
return new Set(table);
|
||||
};
|
||||
|
||||
validationOptions = Object.assign({}, validationOptions); // Shallow cloned
|
||||
validationOptions.tlds = {
|
||||
allow: normalizeTable(validationOptions.tlds.allow),
|
||||
deny: normalizeTable(validationOptions.tlds.deny)
|
||||
};
|
||||
}
|
||||
|
||||
Hoek.assert(validationOptions.minDomainSegments === undefined ||
|
||||
Number.isSafeInteger(validationOptions.minDomainSegments) && validationOptions.minDomainSegments > 0, 'minDomainSegments must be a positive integer');
|
||||
}
|
||||
|
||||
return this._test('email', validationOptions, function (value, state, options) {
|
||||
|
||||
if (Address.email.isValid(value, validationOptions)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('string.email', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
ip(ipOptions = {}) {
|
||||
|
||||
let regex = internals.ipRegex;
|
||||
Hoek.assert(typeof ipOptions === 'object', 'options must be an object');
|
||||
|
||||
if (ipOptions.cidr) {
|
||||
Hoek.assert(typeof ipOptions.cidr === 'string', 'cidr must be a string');
|
||||
ipOptions.cidr = ipOptions.cidr.toLowerCase();
|
||||
|
||||
Hoek.assert(Hoek.contain(internals.cidrPresences, ipOptions.cidr), 'cidr must be one of ' + internals.cidrPresences.join(', '));
|
||||
|
||||
// If we only received a `cidr` setting, create a regex for it. But we don't need to create one if `cidr` is "optional" since that is the default
|
||||
if (!ipOptions.version && ipOptions.cidr !== 'optional') {
|
||||
regex = Ip.createIpRegex(['ipv4', 'ipv6', 'ipvfuture'], ipOptions.cidr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
// Set our default cidr strategy
|
||||
ipOptions.cidr = 'optional';
|
||||
}
|
||||
|
||||
let versions;
|
||||
if (ipOptions.version) {
|
||||
if (!Array.isArray(ipOptions.version)) {
|
||||
ipOptions.version = [ipOptions.version];
|
||||
}
|
||||
|
||||
Hoek.assert(ipOptions.version.length >= 1, 'version must have at least 1 version specified');
|
||||
|
||||
versions = [];
|
||||
for (let i = 0; i < ipOptions.version.length; ++i) {
|
||||
let version = ipOptions.version[i];
|
||||
Hoek.assert(typeof version === 'string', 'version at position ' + i + ' must be a string');
|
||||
version = version.toLowerCase();
|
||||
Hoek.assert(Ip.versions[version], 'version at position ' + i + ' must be one of ' + Object.keys(Ip.versions).join(', '));
|
||||
versions.push(version);
|
||||
}
|
||||
|
||||
// Make sure we have a set of versions
|
||||
versions = Array.from(new Set(versions));
|
||||
|
||||
regex = Ip.createIpRegex(versions, ipOptions.cidr);
|
||||
}
|
||||
|
||||
return this._test('ip', ipOptions, function (value, state, options) {
|
||||
|
||||
if (regex.test(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (versions) {
|
||||
return this.createError('string.ipVersion', { value, cidr: ipOptions.cidr, version: versions }, state, options);
|
||||
}
|
||||
|
||||
return this.createError('string.ip', { value, cidr: ipOptions.cidr }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
uri(uriOptions) {
|
||||
|
||||
let customScheme = '';
|
||||
let allowRelative = false;
|
||||
let relativeOnly = false;
|
||||
let allowQuerySquareBrackets = false;
|
||||
let regex = internals.uriRegex;
|
||||
|
||||
if (uriOptions) {
|
||||
Hoek.assert(typeof uriOptions === 'object', 'options must be an object');
|
||||
|
||||
const unknownOptions = Object.keys(uriOptions).filter((key) => !['scheme', 'allowRelative', 'relativeOnly', 'allowQuerySquareBrackets'].includes(key));
|
||||
Hoek.assert(unknownOptions.length === 0, `options contain unknown keys: ${unknownOptions}`);
|
||||
|
||||
if (uriOptions.scheme) {
|
||||
Hoek.assert(uriOptions.scheme instanceof RegExp || typeof uriOptions.scheme === 'string' || Array.isArray(uriOptions.scheme), 'scheme must be a RegExp, String, or Array');
|
||||
|
||||
if (!Array.isArray(uriOptions.scheme)) {
|
||||
uriOptions.scheme = [uriOptions.scheme];
|
||||
}
|
||||
|
||||
Hoek.assert(uriOptions.scheme.length >= 1, 'scheme must have at least 1 scheme specified');
|
||||
|
||||
// Flatten the array into a string to be used to match the schemes.
|
||||
for (let i = 0; i < uriOptions.scheme.length; ++i) {
|
||||
const scheme = uriOptions.scheme[i];
|
||||
Hoek.assert(scheme instanceof RegExp || typeof scheme === 'string', 'scheme at position ' + i + ' must be a RegExp or String');
|
||||
|
||||
// Add OR separators if a value already exists
|
||||
customScheme = customScheme + (customScheme ? '|' : '');
|
||||
|
||||
// If someone wants to match HTTP or HTTPS for example then we need to support both RegExp and String so we don't escape their pattern unknowingly.
|
||||
if (scheme instanceof RegExp) {
|
||||
customScheme = customScheme + scheme.source;
|
||||
}
|
||||
else {
|
||||
Hoek.assert(/[a-zA-Z][a-zA-Z0-9+-\.]*/.test(scheme), 'scheme at position ' + i + ' must be a valid scheme');
|
||||
customScheme = customScheme + Hoek.escapeRegex(scheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uriOptions.allowRelative) {
|
||||
allowRelative = true;
|
||||
}
|
||||
|
||||
if (uriOptions.relativeOnly) {
|
||||
relativeOnly = true;
|
||||
}
|
||||
|
||||
if (uriOptions.allowQuerySquareBrackets) {
|
||||
allowQuerySquareBrackets = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (customScheme || allowRelative || relativeOnly || allowQuerySquareBrackets) {
|
||||
regex = Uri.createUriRegex(customScheme, allowRelative, relativeOnly, allowQuerySquareBrackets);
|
||||
}
|
||||
|
||||
return this._test('uri', uriOptions, function (value, state, options) {
|
||||
|
||||
if (regex.test(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (relativeOnly) {
|
||||
return this.createError('string.uriRelativeOnly', { value }, state, options);
|
||||
}
|
||||
|
||||
if (customScheme) {
|
||||
return this.createError('string.uriCustomScheme', { scheme: customScheme, value }, state, options);
|
||||
}
|
||||
|
||||
return this.createError('string.uri', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
isoDate() {
|
||||
|
||||
return this._test('isoDate', undefined, function (value, state, options) {
|
||||
|
||||
if (JoiDate._isIsoDate(value)) {
|
||||
if (!options.convert) {
|
||||
return value;
|
||||
}
|
||||
|
||||
const d = new Date(value);
|
||||
if (!isNaN(d.getTime())) {
|
||||
return d.toISOString();
|
||||
}
|
||||
}
|
||||
|
||||
return this.createError('string.isoDate', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
guid(guidOptions) {
|
||||
|
||||
let versionNumbers = '';
|
||||
|
||||
if (guidOptions && guidOptions.version) {
|
||||
if (!Array.isArray(guidOptions.version)) {
|
||||
guidOptions.version = [guidOptions.version];
|
||||
}
|
||||
|
||||
Hoek.assert(guidOptions.version.length >= 1, 'version must have at least 1 valid version specified');
|
||||
const versions = new Set();
|
||||
|
||||
for (let i = 0; i < guidOptions.version.length; ++i) {
|
||||
let version = guidOptions.version[i];
|
||||
Hoek.assert(typeof version === 'string', 'version at position ' + i + ' must be a string');
|
||||
version = version.toLowerCase();
|
||||
const versionNumber = internals.guidVersions[version];
|
||||
Hoek.assert(versionNumber, 'version at position ' + i + ' must be one of ' + Object.keys(internals.guidVersions).join(', '));
|
||||
Hoek.assert(!(versions.has(versionNumber)), 'version at position ' + i + ' must not be a duplicate.');
|
||||
|
||||
versionNumbers += versionNumber;
|
||||
versions.add(versionNumber);
|
||||
}
|
||||
}
|
||||
|
||||
const guidRegex = 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');
|
||||
|
||||
return this._test('guid', guidOptions, function (value, state, options) {
|
||||
|
||||
const results = guidRegex.exec(value);
|
||||
|
||||
if (!results) {
|
||||
return this.createError('string.guid', { value }, state, options);
|
||||
}
|
||||
|
||||
// Matching braces
|
||||
if (internals.guidBrackets[results[1]] !== results[results.length - 1]) {
|
||||
return this.createError('string.guid', { value }, state, options);
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
hex(hexOptions = {}) {
|
||||
|
||||
Hoek.assert(typeof hexOptions === 'object', 'hex options must be an object');
|
||||
Hoek.assert(typeof hexOptions.byteAligned === 'undefined' || typeof hexOptions.byteAligned === 'boolean',
|
||||
'byteAligned must be boolean');
|
||||
|
||||
const byteAligned = hexOptions.byteAligned === true;
|
||||
const regex = /^[a-f0-9]+$/i;
|
||||
|
||||
const obj = this._test('hex', regex, function (value, state, options) {
|
||||
|
||||
if (regex.test(value)) {
|
||||
if (byteAligned && value.length % 2 !== 0) {
|
||||
return this.createError('string.hexAlign', { value }, state, options);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('string.hex', { value }, state, options);
|
||||
});
|
||||
|
||||
if (byteAligned) {
|
||||
obj._flags.byteAligned = true;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
base64(base64Options = {}) {
|
||||
|
||||
// Validation.
|
||||
Hoek.assert(typeof base64Options === 'object', 'base64 options must be an object');
|
||||
Hoek.assert(typeof base64Options.paddingRequired === 'undefined' || typeof base64Options.paddingRequired === 'boolean',
|
||||
'paddingRequired must be boolean');
|
||||
|
||||
// Determine if padding is required.
|
||||
const paddingRequired = base64Options.paddingRequired === false ?
|
||||
base64Options.paddingRequired
|
||||
: base64Options.paddingRequired || true;
|
||||
|
||||
// Set validation based on preference.
|
||||
const regex = paddingRequired ?
|
||||
// Padding is required.
|
||||
/^(?:[A-Za-z0-9+\/]{2}[A-Za-z0-9+\/]{2})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/
|
||||
// Padding is optional.
|
||||
: /^(?:[A-Za-z0-9+\/]{2}[A-Za-z0-9+\/]{2})*(?:[A-Za-z0-9+\/]{2}(==)?|[A-Za-z0-9+\/]{3}=?)?$/;
|
||||
|
||||
return this._test('base64', regex, function (value, state, options) {
|
||||
|
||||
if (regex.test(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('string.base64', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
dataUri(dataUriOptions = {}) {
|
||||
|
||||
const regex = /^data:[\w+.-]+\/[\w+.-]+;((charset=[\w-]+|base64),)?(.*)$/;
|
||||
|
||||
// Determine if padding is required.
|
||||
const paddingRequired = dataUriOptions.paddingRequired === false ?
|
||||
dataUriOptions.paddingRequired
|
||||
: dataUriOptions.paddingRequired || true;
|
||||
|
||||
const base64regex = paddingRequired ?
|
||||
/^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/
|
||||
: /^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}(==)?|[A-Za-z0-9+\/]{3}=?)?$/;
|
||||
|
||||
return this._test('dataUri', regex, function (value, state, options) {
|
||||
|
||||
const matches = value.match(regex);
|
||||
|
||||
if (matches) {
|
||||
if (!matches[2]) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (matches[2] !== 'base64') {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (base64regex.test(matches[3])) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return this.createError('string.dataUri', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
hostname() {
|
||||
|
||||
const regex = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
|
||||
|
||||
return this._test('hostname', undefined, function (value, state, options) {
|
||||
|
||||
if ((value.length <= 255 && regex.test(value)) ||
|
||||
Net.isIPv6(value)) {
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('string.hostname', { value }, state, options);
|
||||
});
|
||||
}
|
||||
|
||||
normalize(form = 'NFC') {
|
||||
|
||||
Hoek.assert(Hoek.contain(internals.normalizationForms, form), 'normalization form must be one of ' + internals.normalizationForms.join(', '));
|
||||
|
||||
const obj = this._test('normalize', form, function (value, state, options) {
|
||||
|
||||
if (options.convert ||
|
||||
value === value.normalize(form)) {
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('string.normalize', { value, form }, state, options);
|
||||
});
|
||||
|
||||
obj._flags.normalize = form;
|
||||
return obj;
|
||||
}
|
||||
|
||||
lowercase() {
|
||||
|
||||
const obj = this._test('lowercase', undefined, function (value, state, options) {
|
||||
|
||||
if (options.convert ||
|
||||
value === value.toLocaleLowerCase()) {
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('string.lowercase', { value }, state, options);
|
||||
});
|
||||
|
||||
obj._flags.case = 'lower';
|
||||
return obj;
|
||||
}
|
||||
|
||||
uppercase() {
|
||||
|
||||
const obj = this._test('uppercase', undefined, function (value, state, options) {
|
||||
|
||||
if (options.convert ||
|
||||
value === value.toLocaleUpperCase()) {
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('string.uppercase', { value }, state, options);
|
||||
});
|
||||
|
||||
obj._flags.case = 'upper';
|
||||
return obj;
|
||||
}
|
||||
|
||||
trim(enabled = true) {
|
||||
|
||||
Hoek.assert(typeof enabled === 'boolean', 'option must be a boolean');
|
||||
|
||||
if ((this._flags.trim && enabled) || (!this._flags.trim && !enabled)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
let obj;
|
||||
if (enabled) {
|
||||
obj = this._test('trim', undefined, function (value, state, options) {
|
||||
|
||||
if (options.convert ||
|
||||
value === value.trim()) {
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('string.trim', { value }, state, options);
|
||||
});
|
||||
}
|
||||
else {
|
||||
obj = this.clone();
|
||||
obj._tests = obj._tests.filter((test) => test.name !== 'trim');
|
||||
}
|
||||
|
||||
obj._flags.trim = enabled;
|
||||
return obj;
|
||||
}
|
||||
|
||||
replace(pattern, replacement) {
|
||||
|
||||
if (typeof pattern === 'string') {
|
||||
pattern = new RegExp(Hoek.escapeRegex(pattern), 'g');
|
||||
}
|
||||
|
||||
Hoek.assert(pattern instanceof RegExp, 'pattern must be a RegExp');
|
||||
Hoek.assert(typeof replacement === 'string', 'replacement must be a String');
|
||||
|
||||
// This can not be considere a test like trim, we can't "reject"
|
||||
// anything from this rule, so just clone the current object
|
||||
const obj = this.clone();
|
||||
|
||||
if (!obj._inner.replacements) {
|
||||
obj._inner.replacements = [];
|
||||
}
|
||||
|
||||
obj._inner.replacements.push({
|
||||
pattern,
|
||||
replacement
|
||||
});
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
truncate(enabled) {
|
||||
|
||||
const value = enabled === undefined ? true : !!enabled;
|
||||
|
||||
if (this._flags.truncate === value) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const obj = this.clone();
|
||||
obj._flags.truncate = value;
|
||||
return obj;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
internals.compare = function (type, compare) {
|
||||
|
||||
return function (limit, encoding) {
|
||||
|
||||
const isRef = Ref.isRef(limit);
|
||||
|
||||
Hoek.assert((Number.isSafeInteger(limit) && limit >= 0) || isRef, 'limit must be a positive integer or reference');
|
||||
Hoek.assert(!encoding || Buffer.isEncoding(encoding), 'Invalid encoding:', encoding);
|
||||
|
||||
return this._test(type, limit, function (value, state, options) {
|
||||
|
||||
let compareTo;
|
||||
if (isRef) {
|
||||
compareTo = limit(state.reference || state.parent, options);
|
||||
|
||||
if (!Number.isSafeInteger(compareTo)) {
|
||||
return this.createError('string.ref', { ref: limit, value: compareTo }, state, options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
compareTo = limit;
|
||||
}
|
||||
|
||||
if (compare(value, compareTo, encoding)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return this.createError('string.' + type, { limit: compareTo, value, encoding }, state, options);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
internals.String.prototype.min = internals.compare('min', (value, limit, encoding) => {
|
||||
|
||||
const length = encoding ? Buffer.byteLength(value, encoding) : value.length;
|
||||
return length >= limit;
|
||||
});
|
||||
|
||||
|
||||
internals.String.prototype.max = internals.compare('max', (value, limit, encoding) => {
|
||||
|
||||
const length = encoding ? Buffer.byteLength(value, encoding) : value.length;
|
||||
return length <= limit;
|
||||
});
|
||||
|
||||
|
||||
internals.String.prototype.length = internals.compare('length', (value, limit, encoding) => {
|
||||
|
||||
const length = encoding ? Buffer.byteLength(value, encoding) : value.length;
|
||||
return length === limit;
|
||||
});
|
||||
|
||||
// Aliases
|
||||
|
||||
internals.String.prototype.uuid = internals.String.prototype.guid;
|
||||
|
||||
module.exports = new internals.String();
|
50
web/node_modules/@hapi/joi/lib/types/string/ip.js
generated
vendored
Executable file
50
web/node_modules/@hapi/joi/lib/types/string/ip.js
generated
vendored
Executable file
|
@ -0,0 +1,50 @@
|
|||
'use strict';
|
||||
|
||||
const RFC3986 = require('./rfc3986');
|
||||
|
||||
|
||||
const internals = {
|
||||
Ip: {
|
||||
cidrs: {
|
||||
ipv4: {
|
||||
required: '\\/(?:' + RFC3986.ipv4Cidr + ')',
|
||||
optional: '(?:\\/(?:' + RFC3986.ipv4Cidr + '))?',
|
||||
forbidden: ''
|
||||
},
|
||||
ipv6: {
|
||||
required: '\\/' + RFC3986.ipv6Cidr,
|
||||
optional: '(?:\\/' + RFC3986.ipv6Cidr + ')?',
|
||||
forbidden: ''
|
||||
},
|
||||
ipvfuture: {
|
||||
required: '\\/' + RFC3986.ipv6Cidr,
|
||||
optional: '(?:\\/' + RFC3986.ipv6Cidr + ')?',
|
||||
forbidden: ''
|
||||
}
|
||||
},
|
||||
versions: {
|
||||
ipv4: RFC3986.IPv4address,
|
||||
ipv6: RFC3986.IPv6address,
|
||||
ipvfuture: RFC3986.IPvFuture
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.Ip.createIpRegex = function (versions, cidr) {
|
||||
|
||||
let regex;
|
||||
for (let i = 0; i < versions.length; ++i) {
|
||||
const version = versions[i];
|
||||
if (!regex) {
|
||||
regex = '^(?:' + internals.Ip.versions[version] + internals.Ip.cidrs[version][cidr];
|
||||
}
|
||||
else {
|
||||
regex += '|' + internals.Ip.versions[version] + internals.Ip.cidrs[version][cidr];
|
||||
}
|
||||
}
|
||||
|
||||
return new RegExp(regex + ')$');
|
||||
};
|
||||
|
||||
module.exports = internals.Ip;
|
214
web/node_modules/@hapi/joi/lib/types/string/rfc3986.js
generated
vendored
Executable file
214
web/node_modules/@hapi/joi/lib/types/string/rfc3986.js
generated
vendored
Executable file
|
@ -0,0 +1,214 @@
|
|||
'use strict';
|
||||
|
||||
const internals = {
|
||||
rfc3986: {}
|
||||
};
|
||||
|
||||
|
||||
internals.generate = function () {
|
||||
|
||||
/**
|
||||
* elements separated by forward slash ("/") are alternatives.
|
||||
*/
|
||||
const or = '|';
|
||||
|
||||
/**
|
||||
* Rule to support zero-padded addresses.
|
||||
*/
|
||||
const zeroPad = '0?';
|
||||
|
||||
/**
|
||||
* DIGIT = %x30-39 ; 0-9
|
||||
*/
|
||||
const digit = '0-9';
|
||||
const digitOnly = '[' + digit + ']';
|
||||
|
||||
/**
|
||||
* ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
|
||||
*/
|
||||
const alpha = 'a-zA-Z';
|
||||
const alphaOnly = '[' + alpha + ']';
|
||||
|
||||
/**
|
||||
* IPv4
|
||||
* cidr = DIGIT ; 0-9
|
||||
* / %x31-32 DIGIT ; 10-29
|
||||
* / "3" %x30-32 ; 30-32
|
||||
*/
|
||||
internals.rfc3986.ipv4Cidr = digitOnly + or + '[1-2]' + digitOnly + or + '3' + '[0-2]';
|
||||
|
||||
/**
|
||||
* IPv6
|
||||
* cidr = DIGIT ; 0-9
|
||||
* / %x31-39 DIGIT ; 10-99
|
||||
* / "1" %x0-1 DIGIT ; 100-119
|
||||
* / "12" %x0-8 ; 120-128
|
||||
*/
|
||||
internals.rfc3986.ipv6Cidr = '(?:' + zeroPad + zeroPad + digitOnly + or + zeroPad + '[1-9]' + digitOnly + or + '1' + '[01]' + digitOnly + or + '12[0-8])';
|
||||
|
||||
/**
|
||||
* HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
|
||||
*/
|
||||
const hexDigit = digit + 'A-Fa-f';
|
||||
const hexDigitOnly = '[' + hexDigit + ']';
|
||||
|
||||
/**
|
||||
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
*/
|
||||
const unreserved = alpha + digit + '-\\._~';
|
||||
|
||||
/**
|
||||
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
|
||||
*/
|
||||
const subDelims = '!\\$&\'\\(\\)\\*\\+,;=';
|
||||
|
||||
/**
|
||||
* pct-encoded = "%" HEXDIG HEXDIG
|
||||
*/
|
||||
const pctEncoded = '%' + hexDigit;
|
||||
|
||||
/**
|
||||
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||
*/
|
||||
const pchar = unreserved + pctEncoded + subDelims + ':@';
|
||||
const pcharOnly = '[' + pchar + ']';
|
||||
|
||||
/**
|
||||
* squareBrackets example: []
|
||||
*/
|
||||
const squareBrackets = '\\[\\]';
|
||||
|
||||
/**
|
||||
* dec-octet = DIGIT ; 0-9
|
||||
* / %x31-39 DIGIT ; 10-99
|
||||
* / "1" 2DIGIT ; 100-199
|
||||
* / "2" %x30-34 DIGIT ; 200-249
|
||||
* / "25" %x30-35 ; 250-255
|
||||
*/
|
||||
const decOctect = '(?:' + zeroPad + zeroPad + digitOnly + or + zeroPad + '[1-9]' + digitOnly + or + '1' + digitOnly + digitOnly + or + '2' + '[0-4]' + digitOnly + or + '25' + '[0-5])';
|
||||
|
||||
/**
|
||||
* IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
|
||||
*/
|
||||
internals.rfc3986.IPv4address = '(?:' + decOctect + '\\.){3}' + decOctect;
|
||||
|
||||
/**
|
||||
* h16 = 1*4HEXDIG ; 16 bits of address represented in hexadecimal
|
||||
* ls32 = ( h16 ":" h16 ) / IPv4address ; least-significant 32 bits of address
|
||||
* IPv6address = 6( h16 ":" ) ls32
|
||||
* / "::" 5( h16 ":" ) ls32
|
||||
* / [ h16 ] "::" 4( h16 ":" ) ls32
|
||||
* / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
|
||||
* / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
|
||||
* / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
|
||||
* / [ *4( h16 ":" ) h16 ] "::" ls32
|
||||
* / [ *5( h16 ":" ) h16 ] "::" h16
|
||||
* / [ *6( h16 ":" ) h16 ] "::"
|
||||
*/
|
||||
const h16 = hexDigitOnly + '{1,4}';
|
||||
const ls32 = '(?:' + h16 + ':' + h16 + '|' + internals.rfc3986.IPv4address + ')';
|
||||
const IPv6SixHex = '(?:' + h16 + ':){6}' + ls32;
|
||||
const IPv6FiveHex = '::(?:' + h16 + ':){5}' + ls32;
|
||||
const IPv6FourHex = '(?:' + h16 + ')?::(?:' + h16 + ':){4}' + ls32;
|
||||
const IPv6ThreeHex = '(?:(?:' + h16 + ':){0,1}' + h16 + ')?::(?:' + h16 + ':){3}' + ls32;
|
||||
const IPv6TwoHex = '(?:(?:' + h16 + ':){0,2}' + h16 + ')?::(?:' + h16 + ':){2}' + ls32;
|
||||
const IPv6OneHex = '(?:(?:' + h16 + ':){0,3}' + h16 + ')?::' + h16 + ':' + ls32;
|
||||
const IPv6NoneHex = '(?:(?:' + h16 + ':){0,4}' + h16 + ')?::' + ls32;
|
||||
const IPv6NoneHex2 = '(?:(?:' + h16 + ':){0,5}' + h16 + ')?::' + h16;
|
||||
const IPv6NoneHex3 = '(?:(?:' + h16 + ':){0,6}' + h16 + ')?::';
|
||||
internals.rfc3986.IPv6address = '(?:' + IPv6SixHex + or + IPv6FiveHex + or + IPv6FourHex + or + IPv6ThreeHex + or + IPv6TwoHex + or + IPv6OneHex + or + IPv6NoneHex + or + IPv6NoneHex2 + or + IPv6NoneHex3 + ')';
|
||||
|
||||
/**
|
||||
* IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
|
||||
*/
|
||||
internals.rfc3986.IPvFuture = 'v' + hexDigitOnly + '+\\.[' + unreserved + subDelims + ':]+';
|
||||
|
||||
/**
|
||||
* scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
||||
*/
|
||||
internals.rfc3986.scheme = alphaOnly + '[' + alpha + digit + '+-\\.]*';
|
||||
|
||||
/**
|
||||
* userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
|
||||
*/
|
||||
const userinfo = '[' + unreserved + pctEncoded + subDelims + ':]*';
|
||||
|
||||
/**
|
||||
* IP-literal = "[" ( IPv6address / IPvFuture ) "]"
|
||||
*/
|
||||
const IPLiteral = '\\[(?:' + internals.rfc3986.IPv6address + or + internals.rfc3986.IPvFuture + ')\\]';
|
||||
|
||||
/**
|
||||
* reg-name = *( unreserved / pct-encoded / sub-delims )
|
||||
*/
|
||||
const regName = '[' + unreserved + pctEncoded + subDelims + ']{0,255}';
|
||||
|
||||
/**
|
||||
* host = IP-literal / IPv4address / reg-name
|
||||
*/
|
||||
const host = '(?:' + IPLiteral + or + internals.rfc3986.IPv4address + or + regName + ')';
|
||||
|
||||
/**
|
||||
* port = *DIGIT
|
||||
*/
|
||||
const port = digitOnly + '*';
|
||||
|
||||
/**
|
||||
* authority = [ userinfo "@" ] host [ ":" port ]
|
||||
*/
|
||||
const authority = '(?:' + userinfo + '@)?' + host + '(?::' + port + ')?';
|
||||
|
||||
/**
|
||||
* segment = *pchar
|
||||
* segment-nz = 1*pchar
|
||||
* path = path-abempty ; begins with "/" or is empty
|
||||
* / path-absolute ; begins with "/" but not "//"
|
||||
* / path-noscheme ; begins with a non-colon segment
|
||||
* / path-rootless ; begins with a segment
|
||||
* / path-empty ; zero characters
|
||||
* path-abempty = *( "/" segment )
|
||||
* path-absolute = "/" [ segment-nz *( "/" segment ) ]
|
||||
* path-rootless = segment-nz *( "/" segment )
|
||||
*/
|
||||
const segment = pcharOnly + '*';
|
||||
const segmentNz = pcharOnly + '+';
|
||||
const segmentNzNc = '[' + unreserved + pctEncoded + subDelims + '@' + ']+';
|
||||
const pathEmpty = '';
|
||||
const pathAbEmpty = '(?:\\/' + segment + ')*';
|
||||
const pathAbsolute = '\\/(?:' + segmentNz + pathAbEmpty + ')?';
|
||||
const pathRootless = segmentNz + pathAbEmpty;
|
||||
const pathNoScheme = segmentNzNc + pathAbEmpty;
|
||||
|
||||
/**
|
||||
* hier-part = "//" authority path
|
||||
*/
|
||||
internals.rfc3986.hierPart = '(?:' + '(?:\\/\\/' + authority + pathAbEmpty + ')' + or + pathAbsolute + or + pathRootless + ')';
|
||||
|
||||
/**
|
||||
* relative-part = "//" authority path-abempty
|
||||
* / path-absolute
|
||||
* / path-noscheme
|
||||
* / path-empty
|
||||
*/
|
||||
internals.rfc3986.relativeRef = '(?:' + '(?:\\/\\/' + authority + pathAbEmpty + ')' + or + pathAbsolute + or + pathNoScheme + or + pathEmpty + ')';
|
||||
|
||||
/**
|
||||
* query = *( pchar / "/" / "?" )
|
||||
*/
|
||||
internals.rfc3986.query = '[' + pchar + '\\/\\?]*(?=#|$)'; //Finish matching either at the fragment part or end of the line.
|
||||
|
||||
/**
|
||||
* query = *( pchar / "[" / "]" / "/" / "?" )
|
||||
*/
|
||||
internals.rfc3986.queryWithSquareBrackets = '[' + pchar + squareBrackets + '\\/\\?]*(?=#|$)'; //Finish matching either at the fragment part or end of the line.
|
||||
|
||||
/**
|
||||
* fragment = *( pchar / "/" / "?" )
|
||||
*/
|
||||
internals.rfc3986.fragment = '[' + pchar + '\\/\\?]*';
|
||||
};
|
||||
|
||||
|
||||
internals.generate();
|
||||
|
||||
module.exports = internals.rfc3986;
|
41
web/node_modules/@hapi/joi/lib/types/string/uri.js
generated
vendored
Executable file
41
web/node_modules/@hapi/joi/lib/types/string/uri.js
generated
vendored
Executable file
|
@ -0,0 +1,41 @@
|
|||
'use strict';
|
||||
|
||||
const RFC3986 = require('./rfc3986');
|
||||
|
||||
|
||||
const internals = {
|
||||
Uri: {
|
||||
createUriRegex: function (optionalScheme, allowRelative, relativeOnly, allowQuerySquareBrackets) {
|
||||
|
||||
let scheme = RFC3986.scheme;
|
||||
let prefix;
|
||||
|
||||
if (relativeOnly) {
|
||||
prefix = '(?:' + RFC3986.relativeRef + ')';
|
||||
}
|
||||
else {
|
||||
// If we were passed a scheme, use it instead of the generic one
|
||||
if (optionalScheme) {
|
||||
|
||||
// Have to put this in a non-capturing group to handle the OR statements
|
||||
scheme = '(?:' + optionalScheme + ')';
|
||||
}
|
||||
|
||||
const withScheme = '(?:' + scheme + ':' + RFC3986.hierPart + ')';
|
||||
|
||||
prefix = allowRelative ? '(?:' + withScheme + '|' + RFC3986.relativeRef + ')' : withScheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
|
||||
*
|
||||
* OR
|
||||
*
|
||||
* relative-ref = relative-part [ "?" query ] [ "#" fragment ]
|
||||
*/
|
||||
return new RegExp('^' + prefix + '(?:\\?' + (allowQuerySquareBrackets ? RFC3986.queryWithSquareBrackets : RFC3986.query) + ')?' + '(?:#' + RFC3986.fragment + ')?$');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = internals.Uri;
|
90
web/node_modules/@hapi/joi/lib/types/symbol/index.js
generated
vendored
Executable file
90
web/node_modules/@hapi/joi/lib/types/symbol/index.js
generated
vendored
Executable file
|
@ -0,0 +1,90 @@
|
|||
'use strict';
|
||||
|
||||
const Util = require('util');
|
||||
|
||||
const Hoek = require('@hapi/hoek');
|
||||
|
||||
const Any = require('../any');
|
||||
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
internals.Map = class extends Map {
|
||||
|
||||
slice() {
|
||||
|
||||
return new internals.Map(this);
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
return Util.inspect(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
internals.Symbol = class extends Any {
|
||||
|
||||
constructor() {
|
||||
|
||||
super();
|
||||
this._type = 'symbol';
|
||||
this._inner.map = new internals.Map();
|
||||
}
|
||||
|
||||
_base(value, state, options) {
|
||||
|
||||
if (options.convert) {
|
||||
const lookup = this._inner.map.get(value);
|
||||
if (lookup) {
|
||||
value = lookup;
|
||||
}
|
||||
|
||||
if (this._flags.allowOnly) {
|
||||
return {
|
||||
value,
|
||||
errors: (typeof value === 'symbol') ? null : this.createError('symbol.map', { value, map: this._inner.map }, state, options)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
value,
|
||||
errors: (typeof value === 'symbol') ? null : this.createError('symbol.base', { value }, state, options)
|
||||
};
|
||||
}
|
||||
|
||||
map(iterable) {
|
||||
|
||||
if (iterable && !iterable[Symbol.iterator] && typeof iterable === 'object') {
|
||||
iterable = Object.entries(iterable);
|
||||
}
|
||||
|
||||
Hoek.assert(iterable && iterable[Symbol.iterator], 'Iterable must be an iterable or object');
|
||||
const obj = this.clone();
|
||||
|
||||
const symbols = [];
|
||||
for (const entry of iterable) {
|
||||
Hoek.assert(entry && entry[Symbol.iterator], 'Entry must be an iterable');
|
||||
const [key, value] = entry;
|
||||
|
||||
Hoek.assert(typeof key !== 'object' && typeof key !== 'function' && typeof key !== 'symbol', 'Key must not be an object, function, or Symbol');
|
||||
Hoek.assert(typeof value === 'symbol', 'Value must be a Symbol');
|
||||
obj._inner.map.set(key, value);
|
||||
symbols.push(value);
|
||||
}
|
||||
|
||||
return obj.valid(...symbols);
|
||||
}
|
||||
|
||||
describe() {
|
||||
|
||||
const description = super.describe();
|
||||
description.map = new Map(this._inner.map);
|
||||
return description;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
module.exports = new internals.Symbol();
|
8
web/node_modules/@hapi/joi/lib/types/symbols.js
generated
vendored
Executable file
8
web/node_modules/@hapi/joi/lib/types/symbols.js
generated
vendored
Executable file
|
@ -0,0 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
const internals = {};
|
||||
|
||||
|
||||
module.exports = {
|
||||
settingsCache: Symbol('settingsCache')
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue