WIP - add extractor, generate snippet_data

This commit is contained in:
Stefan Fejes
2019-08-20 15:52:05 +02:00
parent 88084d3d30
commit cc8f1d8a7a
37396 changed files with 4588842 additions and 133 deletions

64
node_modules/joi/lib/cast.js generated vendored Normal file
View File

@ -0,0 +1,64 @@
'use strict';
// Load modules
const Hoek = require('hoek');
const Ref = require('./ref');
// Type modules are delay-loaded to prevent circular dependencies
// Declare internals
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);
};

357
node_modules/joi/lib/errors.js generated vendored Executable file
View File

@ -0,0 +1,357 @@
'use strict';
// Load modules
const Hoek = require('hoek');
const Language = require('./language');
// Declare internals
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) {
format = (Hoek.reach(localized, 'key') || Hoek.reach(Language.errors, 'key')) + format;
}
return format.replace(/\{\{(\!?)([^}]+)\}\}/g, ($0, isSecure, name) => {
const value = Hoek.reach(this.context, name);
const normalized = internals.stringify(value, wrapArrays);
return (isSecure ? Hoek.escapeHtml(normalized) : normalized);
});
}
};
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 || !errors.length) {
return null;
}
// Construct error
let message = '';
const details = [];
const processErrors = function (localErrors, parent) {
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') {
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 && item.context.reason.length) {
const override = processErrors(item.context.reason, item.path);
if (override) {
return override;
}
}
else {
details.push({
message: 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;
};

434
node_modules/joi/lib/index.js generated vendored Normal file
View File

@ -0,0 +1,434 @@
'use strict';
// Load modules
const Hoek = require('hoek');
const Any = require('./types/any');
const Cast = require('./cast');
const Errors = require('./errors');
const Lazy = require('./types/lazy');
const Ref = require('./ref');
// Declare internals
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')
};
internals.applyDefaults = function (schema) {
Hoek.assert(this, 'Must be invoked on a Joi instance.');
if (this._defaults) {
schema = this._defaults(schema);
}
schema._currentJoi = this;
return schema;
};
internals.root = function () {
const any = new Any();
const root = any.clone();
Any.prototype._currentJoi = root;
root._currentJoi = root;
root.any = function () {
Hoek.assert(arguments.length === 0, 'Joi.any() does not allow arguments.');
return internals.applyDefaults.call(this, any);
};
root.alternatives = root.alt = function () {
const alternatives = internals.applyDefaults.call(this, internals.alternatives);
return arguments.length ? alternatives.try.apply(alternatives, arguments) : alternatives;
};
root.array = function () {
Hoek.assert(arguments.length === 0, 'Joi.array() does not allow arguments.');
return internals.applyDefaults.call(this, internals.array);
};
root.boolean = root.bool = function () {
Hoek.assert(arguments.length === 0, 'Joi.boolean() does not allow arguments.');
return internals.applyDefaults.call(this, internals.boolean);
};
root.binary = function () {
Hoek.assert(arguments.length === 0, 'Joi.binary() does not allow arguments.');
return internals.applyDefaults.call(this, internals.binary);
};
root.date = function () {
Hoek.assert(arguments.length === 0, 'Joi.date() does not allow arguments.');
return internals.applyDefaults.call(this, internals.date);
};
root.func = function () {
Hoek.assert(arguments.length === 0, 'Joi.func() does not allow arguments.');
return internals.applyDefaults.call(this, internals.func);
};
root.number = function () {
Hoek.assert(arguments.length === 0, 'Joi.number() does not allow arguments.');
return internals.applyDefaults.call(this, internals.number);
};
root.object = function () {
const object = internals.applyDefaults.call(this, internals.object);
return arguments.length ? object.keys.apply(object, arguments) : object;
};
root.string = function () {
Hoek.assert(arguments.length === 0, 'Joi.string() does not allow arguments.');
return internals.applyDefaults.call(this, internals.string);
};
root.ref = function () {
return Ref.create.apply(null, arguments);
};
root.isRef = function (ref) {
return Ref.isRef(ref);
};
root.validate = function (value /*, [schema], [options], callback */) {
const last = arguments[arguments.length - 1];
const callback = typeof last === 'function' ? last : null;
const count = arguments.length - (callback ? 1 : 0);
if (count === 1) {
return any.validate(value, callback);
}
const options = count === 3 ? arguments[2] : {};
const schema = root.compile(arguments[1]);
return schema._validateWithOptions(value, options, callback);
};
root.describe = function () {
const schema = arguments.length ? root.compile(arguments[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) {
root.attempt(value, schema, message);
};
root.attempt = function (value, schema, message) {
const result = root.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(typeof path === 'string', 'path must be a string');
if (path === '') {
return schema;
}
const parts = path.split('.');
const children = schema._inner.children;
if (!children) {
return;
}
const key = parts[0];
for (let i = 0; i < children.length; ++i) {
const child = children[i];
if (child.key === key) {
return this.reach(child.schema, path.substr(key.length + 1));
}
}
};
root.lazy = function (fn) {
return Lazy.set(fn);
};
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.extend = function () {
const extensions = Hoek.flatten(Array.prototype.slice.call(arguments));
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);
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) {
this._settings = this._settings || { language: {} };
this._settings.language = Hoek.applyToDefaults(this._settings.language, {
[extension.name]: extension.language
});
}
}
};
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 () { // eslint-disable-line no-loop-func
if (arguments.length > ruleArgs.length) {
throw new Error('Unexpected number of arguments');
}
const args = Array.prototype.slice.call(arguments);
let hasRef = false;
let arg = {};
for (let k = 0; k < ruleArgs.length; ++k) {
arg[ruleArgs[k]] = args[k];
if (!hasRef && Ref.isRef(args[k])) {
hasRef = true;
}
}
if (validateArgs) {
arg = joi.attempt(arg, validateArgs);
}
let schema;
if (rule.validate) {
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;
}
}
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 () {
return internals.applyDefaults.call(this, instance);
};
}
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();

156
node_modules/joi/lib/language.js generated vendored Normal file
View File

@ -0,0 +1,156 @@
'use strict';
// Load modules
// Declare internals
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',
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',
format: 'must be a string with one of the following formats {{format}}',
strict: 'must be a valid date',
min: 'must be larger than or equal to "{{limit}}"',
max: 'must be less than or equal to "{{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}}',
or: 'must contain at least one of {{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',
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}}',
float: 'must be a float or double',
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}}'
},
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',
base64: 'must be a valid base64 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'
}
};

53
node_modules/joi/lib/ref.js generated vendored Normal file
View File

@ -0,0 +1,53 @@
'use strict';
// Load modules
const Hoek = require('hoek');
// Declare internals
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);
}
};

24
node_modules/joi/lib/schemas.js generated vendored Normal file
View File

@ -0,0 +1,24 @@
'use strict';
// Load modules
const Joi = require('../');
// Declare internals
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'),
raw: Joi.boolean(),
context: Joi.object(),
strip: Joi.boolean(),
noDefaults: Joi.boolean()
}).strict();

111
node_modules/joi/lib/set.js generated vendored Normal file
View File

@ -0,0 +1,111 @@
'use strict';
const Ref = require('./ref');
module.exports = class Set {
constructor() {
this._set = [];
}
add(value, refs) {
if (!Ref.isRef(value) && this.has(value, null, null, false)) {
return;
}
if (refs !== undefined) { // If it's a merge, we don't have any refs
Ref.push(refs, value);
}
this._set.push(value);
return this;
}
merge(add, remove) {
for (let i = 0; i < add._set.length; ++i) {
this.add(add._set[i]);
}
for (let i = 0; i < remove._set.length; ++i) {
this.remove(remove._set[i]);
}
return this;
}
remove(value) {
this._set = this._set.filter((item) => value !== item);
return this;
}
has(value, state, options, insensitive) {
for (let i = 0; i < this._set.length; ++i) {
let items = this._set[i];
if (state && Ref.isRef(items)) { // Only resolve references if there is a state, otherwise it's a merge
items = items(state.reference || state.parent, options);
}
if (!Array.isArray(items)) {
items = [items];
}
for (let j = 0; j < items.length; ++j) {
const item = items[j];
if (typeof value !== typeof item) {
continue;
}
if (value === item ||
(value instanceof Date && item instanceof Date && value.getTime() === item.getTime()) ||
(insensitive && typeof value === 'string' && value.toLowerCase() === item.toLowerCase()) ||
(Buffer.isBuffer(value) && Buffer.isBuffer(item) && value.length === item.length && value.toString('binary') === item.toString('binary'))) {
return true;
}
}
}
return false;
}
values(options) {
if (options && options.stripUndefined) {
const values = [];
for (let i = 0; i < this._set.length; ++i) {
const item = this._set[i];
if (item !== undefined) {
values.push(item);
}
}
return values;
}
return this._set.slice();
}
slice() {
const newSet = new Set();
newSet._set = this._set.slice();
return newSet;
}
concat(source) {
const newSet = new Set();
newSet._set = this._set.concat(source._set);
return newSet;
}
};

188
node_modules/joi/lib/types/alternatives/index.js generated vendored Normal file
View File

@ -0,0 +1,188 @@
'use strict';
// Load modules
const Hoek = require('hoek');
const Any = require('../any');
const Cast = require('../../cast');
const Ref = require('../../ref');
// Declare internals
const internals = {};
internals.Alternatives = class extends Any {
constructor() {
super();
this._type = 'alternatives';
this._invalids.remove(null);
this._inner.matches = [];
}
_base(value, state, options) {
let 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 = errors.concat(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 */) {
const schemas = Hoek.flatten(Array.prototype.slice.call(arguments));
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 = obj._refs.concat(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 = obj._refs.concat(item.is._refs);
}
if (item.then && item.then._refs) {
obj._refs = obj._refs.concat(item.then._refs);
}
if (item.otherwise && item.otherwise._refs) {
obj._refs = obj._refs.concat(item.otherwise._refs);
}
obj._inner.matches.push(item);
return obj;
}
describe() {
const description = Any.prototype.describe.call(this);
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();

916
node_modules/joi/lib/types/any/index.js generated vendored Normal file
View File

@ -0,0 +1,916 @@
'use strict';
// Load modules
const Hoek = require('hoek');
const Ref = require('../../ref');
const Errors = require('../../errors');
let Alternatives = null; // Delay-loaded to prevent circular dependencies
let Cast = null;
// Declare internals
const internals = {
Set: require('../../set')
};
internals.defaults = {
abortEarly: true,
convert: true,
allowUnknown: false,
skipFunctions: false,
stripUnknown: false,
language: {},
presence: 'optional',
strip: false,
noDefaults: false
// context: null
};
module.exports = internals.Any = class {
constructor() {
Cast = Cast || require('../../cast');
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
}
get schemaType() {
return this._type;
}
createError(type, context, state, options, flags) {
return Errors.create(type, context, state, options, flags || this._flags);
}
createOverrideError(type, context, state, options, message, template) {
return Errors.create(type, context, state, options, this._flags, message, template);
}
checkOptions(options) {
const 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 = internals.concatSettings(this._settings);
obj._baseType = this._baseType;
obj._valids = Hoek.clone(this._valids);
obj._invalids = Hoek.clone(this._invalids);
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 ? internals.concatSettings(obj._settings, schema._settings) : schema._settings;
obj._valids.merge(schema._valids, schema._invalids);
obj._invalids.merge(schema._invalids, schema._valids);
obj._tests = obj._tests.concat(schema._tests);
obj._refs = obj._refs.concat(schema._refs);
Hoek.merge(obj._flags, schema._flags);
obj._description = schema._description || obj._description;
obj._unit = schema._unit || obj._unit;
obj._notes = obj._notes.concat(schema._notes);
obj._tags = obj._tags.concat(schema._tags);
obj._examples = obj._examples.concat(schema._examples);
obj._meta = obj._meta.concat(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;
}
options(options) {
Hoek.assert(!options.context, 'Cannot override context');
this.checkOptions(options);
const obj = this.clone();
obj._settings = internals.concatSettings(obj._settings, options);
return obj;
}
strict(isStrict) {
const obj = this.clone();
obj._settings = obj._settings || {};
obj._settings.convert = isStrict === undefined ? false : !isStrict;
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) {
Hoek.assert(err && (err instanceof Error || typeof err === 'function'), 'Must provide a valid Error object or a function');
const obj = this.clone();
obj._flags.error = err;
return obj;
}
allow() {
const obj = this.clone();
const values = Hoek.flatten(Array.prototype.slice.call(arguments));
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() {
const obj = this.allow.apply(this, arguments);
obj._flags.allowOnly = true;
return obj;
}
invalid(value) {
const obj = this.clone();
const values = Hoek.flatten(Array.prototype.slice.call(arguments));
for (let i = 0; i < values.length; ++i) {
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].apply(this, 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(value) {
Hoek.assert(arguments.length, 'Missing example');
const result = this._validate(value, null, internals.defaults);
Hoek.assert(!result.errors, 'Bad example:', result.errors && Errors.process(result.errors, value));
const obj = this.clone();
obj._examples.push(value);
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 || { key: '', path: [], parent: null, reference };
if (this._settings) {
options = internals.concatSettings(options, this._settings);
}
let errors = [];
const finish = () => {
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') {
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
};
};
if (this._coerce) {
const coerced = this._coerce.call(this, value, state, options);
if (coerced.errors) {
value = coerced.value;
errors = errors.concat(coerced.errors);
return finish(); // 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 finish();
}
}
}
else if (presence === 'required' &&
value === undefined) {
errors.push(this.createError('any.required', null, state, options));
return finish();
}
else if (presence === 'forbidden') {
if (value === undefined) {
return finish();
}
errors.push(this.createError('any.unknown', null, state, options));
return finish();
}
// Check allowed and denied values using the original value
if (this._valids.has(value, state, options, this._flags.insensitive)) {
return finish();
}
if (this._invalids.has(value, state, options, this._flags.insensitive)) {
errors.push(this.createError(value === '' ? 'any.empty' : 'any.invalid', null, state, options));
if (options.abortEarly ||
value === undefined) { // No reason to keep validating missing value
return finish();
}
}
// Convert value and validate type
if (this._base) {
const base = this._base.call(this, value, state, options);
if (base.errors) {
value = base.value;
errors = errors.concat(base.errors);
return finish(); // Base error always aborts early
}
if (base.value !== value) {
value = base.value;
// Check allowed and denied values using the converted value
if (this._valids.has(value, state, options, this._flags.insensitive)) {
return finish();
}
if (this._invalids.has(value, state, options, this._flags.insensitive)) {
errors.push(this.createError(value === '' ? 'any.empty' : 'any.invalid', null, state, options));
if (options.abortEarly) {
return finish();
}
}
}
}
// Required values did not match
if (this._flags.allowOnly) {
errors.push(this.createError('any.allowOnly', { valids: this._valids.values({ stripUndefined: true }) }, state, options));
if (options.abortEarly) {
return finish();
}
}
// Helper.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 finish();
}
}
else {
value = ret;
}
}
return finish();
}
_validateWithOptions(value, options, callback) {
if (options) {
this.checkOptions(options);
}
const settings = internals.concatSettings(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._try = function (fn, args) {
let err;
let result;
try {
result = fn.apply(null, args);
}
catch (e) {
err = e;
}
return {
value: result,
error: err
};
};
internals.concatSettings = function (target, source) {
// Used to avoid cloning context
if (!target &&
!source) {
return null;
}
const obj = {};
if (target) {
Object.assign(obj, target);
}
if (source) {
const sKeys = Object.keys(source);
for (let i = 0; i < sKeys.length; ++i) {
const key = sKeys[i];
if (key !== 'language' ||
!obj.hasOwnProperty(key)) {
obj[key] = source[key];
}
else {
obj[key] = Hoek.applyToDefaults(obj[key], source[key]);
}
}
}
return obj;
};

658
node_modules/joi/lib/types/array/index.js generated vendored Normal file
View File

@ -0,0 +1,658 @@
'use strict';
// Load modules
const Any = require('../any');
const Cast = require('../../cast');
const Ref = require('../../ref');
const Hoek = require('hoek');
// Declare internals
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) {
internals.safeParse(value, result);
}
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.call(this, 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.call(this, 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.concat(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.concat(i) : state.path;
const localState = { key, path, parent: state.parent, reference: 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;
}
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;
}
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 === true ? true : !!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.call(this, errors, requireds, state, options);
}
if (ordereds.length) {
this._fillOrderedErrors.call(this, errors, ordereds, state, options);
}
return errors.length ? errors : null;
}
describe() {
const description = Any.prototype.describe.call(this);
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());
}
}
return description;
}
items() {
const obj = this.clone();
Hoek.flatten(Array.prototype.slice.call(arguments)).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() {
const obj = this.clone();
Hoek.flatten(Array.prototype.slice.call(arguments)).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._test('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.key }, 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._test('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._test('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);
});
}
unique(comparator) {
Hoek.assert(comparator === undefined ||
typeof comparator === 'function' ||
typeof comparator === 'string', 'comparator must be a function or a string');
const settings = {};
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: {},
number: {},
undefined: {},
boolean: {},
object: new Map(),
function: new Map(),
custom: new Map()
};
const compare = settings.comparator || Hoek.deepEqual;
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 = {
key: state.key,
path: state.path.concat(i),
parent: state.parent,
reference: 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 (records[item] !== undefined) {
const localState = {
key: state.key,
path: state.path.concat(i),
parent: state.parent,
reference: 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.call(this, errors, requiredOrdereds, state, options);
}
}
};
internals.safeParse = function (value, result) {
try {
const converted = JSON.parse(value);
if (Array.isArray(converted)) {
result.value = converted;
}
}
catch (e) { }
};
module.exports = new internals.Array();

100
node_modules/joi/lib/types/binary/index.js generated vendored Normal file
View File

@ -0,0 +1,100 @@
'use strict';
// Load modules
const Any = require('../any');
const Hoek = require('hoek');
// Declare internals
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 = new Buffer(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();

98
node_modules/joi/lib/types/boolean/index.js generated vendored Normal file
View File

@ -0,0 +1,98 @@
'use strict';
// Load modules
const Any = require('../any');
const Hoek = require('hoek');
// Declare internals
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', null, state, options);
return result;
}
truthy() {
const obj = this.clone();
const values = Hoek.flatten(Array.prototype.slice.call(arguments));
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() {
const obj = this.clone();
const values = Hoek.flatten(Array.prototype.slice.call(arguments));
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 = Any.prototype.describe.call(this);
description.truthy = [true].concat(this._inner.truthySet.values());
description.falsy = [false].concat(this._inner.falsySet.values());
return description;
}
};
module.exports = new internals.Boolean();

177
node_modules/joi/lib/types/date/index.js generated vendored Normal file
View File

@ -0,0 +1,177 @@
'use strict';
// Load modules
const Any = require('../any');
const Ref = require('../../ref');
const Hoek = require('hoek');
// Declare internals
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', null, 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}`, null, 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))) {
if (typeof value === 'string' &&
/^[+-]?\d+(\.\d+)?$/.test(value)) {
value = parseFloat(value);
}
let date;
if (format && internals.isIsoDate(format)) {
date = format.test(value) ? new Date(value) : internals.invalidDate;
}
else if (timestamp && multiplier) {
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) {
type = type || 'javascript';
const allowed = ['javascript', 'unix'];
Hoek.assert(allowed.indexOf(type) !== -1, '"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) {
compareTo = internals.Date.toDate(date(state.reference || state.parent, options));
if (!compareTo) {
return this.createError('date.ref', { ref: date.key }, 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) }, state, options);
});
};
};
internals.Date.prototype.min = internals.compare('min', (value, date) => value >= date);
internals.Date.prototype.max = internals.compare('max', (value, date) => value <= date);
module.exports = new internals.Date();

90
node_modules/joi/lib/types/func/index.js generated vendored Normal file
View File

@ -0,0 +1,90 @@
'use strict';
// Load modules
const Hoek = require('hoek');
const ObjectType = require('../object');
const Ref = require('../../ref');
// Declare internals
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', null, 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', null, state, options);
});
}
};
module.exports = new internals.Func();

53
node_modules/joi/lib/types/lazy/index.js generated vendored Normal file
View File

@ -0,0 +1,53 @@
'use strict';
// Load modules
const Any = require('../any');
const Hoek = require('hoek');
// Declare internals
const internals = {};
internals.Lazy = class extends Any {
constructor() {
super();
this._type = 'lazy';
}
_base(value, state, options) {
const result = { value };
const lazy = this._flags.lazy;
if (!lazy) {
result.errors = this.createError('lazy.base', null, state, options);
return result;
}
const schema = lazy();
if (!(schema instanceof Any)) {
result.errors = this.createError('lazy.schema', null, state, options);
return result;
}
return schema._validate(value, state, options);
}
set(fn) {
Hoek.assert(typeof fn === 'function', 'You must provide a function as first argument');
const obj = this.clone();
obj._flags.lazy = fn;
return obj;
}
};
module.exports = new internals.Lazy();

173
node_modules/joi/lib/types/number/index.js generated vendored Normal file
View File

@ -0,0 +1,173 @@
'use strict';
// Load modules
const Any = require('../any');
const Ref = require('../../ref');
const Hoek = require('hoek');
// Declare internals
const internals = {
precisionRx: /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/
};
internals.Number = class extends Any {
constructor() {
super();
this._type = 'number';
this._invalids.add(Infinity);
this._invalids.add(-Infinity);
}
_base(value, state, options) {
const result = {
errors: null,
value
};
if (typeof value === 'string' &&
options.convert) {
const number = parseFloat(value);
result.value = (isNaN(number) || !isFinite(value)) ? NaN : number;
}
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;
}
result.errors = isNumber ? null : this.createError('number.base', null, 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 Number.isSafeInteger(value) ? value : this.createError('number.integer', { value }, state, options);
});
}
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;
}
};
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();

896
node_modules/joi/lib/types/object/index.js generated vendored Normal file
View File

@ -0,0 +1,896 @@
'use strict';
// Load modules
const Hoek = require('hoek');
const Topo = require('topo');
const Any = require('../any');
const Errors = require('../../errors');
const Cast = require('../../cast');
// Declare internals
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 = [];
}
_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) {
value = internals.safeParse(value);
}
const type = this._flags.func ? 'function' : 'object';
if (!value ||
typeof value !== type ||
Array.isArray(value)) {
errors.push(this.createError(type + '.base', null, 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 () {
return value.apply(this, arguments);
};
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 = Hoek.mapToObject(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];
delete unprocessed[key];
const localState = { key, path: state.path.concat(key), parent: target, reference: 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
let unprocessedKeys = Object.keys(unprocessed);
if (unprocessedKeys.length &&
this._inner.patterns.length) {
for (let i = 0; i < unprocessedKeys.length; ++i) {
const key = unprocessedKeys[i];
const localState = { key, path: state.path.concat(key), parent: target, reference: state.reference };
const item = target[key];
for (let j = 0; j < this._inner.patterns.length; ++j) {
const pattern = this._inner.patterns[j];
if (pattern.regex.test(key)) {
delete unprocessed[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();
}
}
if (result.value !== undefined) {
target[key] = result.value;
}
}
}
}
unprocessedKeys = Object.keys(unprocessed);
}
if ((this._inner.children || this._inner.patterns.length) && unprocessedKeys.length) {
if ((options.stripUnknown && this._flags.allowUnknown !== true) ||
options.skipFunctions) {
const stripUnknown = options.stripUnknown
? (options.stripUnknown === true ? true : !!options.stripUnknown.objects)
: false;
for (let i = 0; i < unprocessedKeys.length; ++i) {
const key = unprocessedKeys[i];
if (stripUnknown) {
delete target[key];
delete unprocessed[key];
}
else if (typeof target[key] === 'function') {
delete unprocessed[key];
}
}
unprocessedKeys = Object.keys(unprocessed);
}
if (unprocessedKeys.length &&
(this._flags.allowUnknown !== undefined ? !this._flags.allowUnknown : !options.allowUnknown)) {
for (let i = 0; i < unprocessedKeys.length; ++i) {
const unprocessedKey = unprocessedKeys[i];
errors.push(this.createError('object.allowUnknown', { child: unprocessedKey }, { key: unprocessedKey, path: state.path.concat(unprocessedKey) }, options, {}));
}
}
}
// Validate dependencies
for (let i = 0; i < this._inner.dependencies.length; ++i) {
const dep = this._inner.dependencies[i];
const err = internals[dep.type].call(this, dep.key !== null && target[dep.key], dep.peers, target, { key: dep.key, path: dep.key === null ? state.path : state.path.concat(dep.key) }, 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.indexOf(child.key) === -1) {
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;
}
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 }, 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 }, 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 }, state, options);
});
}
pattern(pattern, schema) {
Hoek.assert(pattern instanceof RegExp, 'Invalid regular expression');
Hoek.assert(schema !== undefined, 'Invalid rule');
pattern = new RegExp(pattern.source, pattern.ignoreCase ? 'i' : undefined); // Future version should break this and forbid unsupported regex flags
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();
obj._inner.patterns.push({ regex: 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) {
return this._dependency('with', key, peers);
}
without(key, peers) {
return this._dependency('without', key, peers);
}
xor() {
const peers = Hoek.flatten(Array.prototype.slice.call(arguments));
return this._dependency('xor', null, peers);
}
or() {
const peers = Hoek.flatten(Array.prototype.slice.call(arguments));
return this._dependency('or', null, peers);
}
and() {
const peers = Hoek.flatten(Array.prototype.slice.call(arguments));
return this._dependency('and', null, peers);
}
nand() {
const peers = Hoek.flatten(Array.prototype.slice.call(arguments));
return this._dependency('nand', null, peers);
}
requiredKeys(children) {
children = Hoek.flatten(Array.prototype.slice.call(arguments));
return this.applyFunctionToChildren(children, 'required');
}
optionalKeys(children) {
children = Hoek.flatten(Array.prototype.slice.call(arguments));
return this.applyFunctionToChildren(children, 'optional');
}
forbiddenKeys(children) {
children = Hoek.flatten(Array.prototype.slice.call(arguments));
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].apply(this, 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 = Any.prototype.describe.call(this);
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];
description.patterns.push({ regex: pattern.regex.toString(), 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';
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 = Hoek.merge({}, state);
localState.key = key;
localState.path = ref.path;
return this.createError('object.assert', { ref: path, message }, localState, options);
});
}
type(constructor, name) {
Hoek.assert(typeof constructor === 'function', 'type must be a constructor function');
const typeData = {
name: name || constructor.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 }, state, options);
});
}
};
internals.safeParse = function (value) {
try {
return JSON.parse(value);
}
catch (parseErr) {}
return value;
};
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 = children.find((child) => child.key === key);
return matchingChild ? matchingChild.schema._getLabel(key) : key;
};
if (Array.isArray(keys)) {
return keys.map(findLabel);
}
return findLabel(keys);
};
internals.with = function (value, peers, parent, state, options) {
if (value === undefined) {
return value;
}
for (let i = 0; i < peers.length; ++i) {
const peer = peers[i];
if (!Object.prototype.hasOwnProperty.call(parent, peer) ||
parent[peer] === undefined) {
return this.createError('object.with', {
main: state.key,
mainWithLabel: internals.keysToLabels(this, state.key),
peer,
peerWithLabel: internals.keysToLabels(this, peer)
}, state, options);
}
}
return value;
};
internals.without = function (value, peers, parent, state, options) {
if (value === undefined) {
return value;
}
for (let i = 0; i < peers.length; ++i) {
const peer = peers[i];
if (Object.prototype.hasOwnProperty.call(parent, peer) &&
parent[peer] !== undefined) {
return this.createError('object.without', {
main: state.key,
mainWithLabel: internals.keysToLabels(this, state.key),
peer,
peerWithLabel: internals.keysToLabels(this, peer)
}, state, options);
}
}
return value;
};
internals.xor = function (value, peers, parent, state, options) {
const present = [];
for (let i = 0; i < peers.length; ++i) {
const peer = peers[i];
if (Object.prototype.hasOwnProperty.call(parent, peer) &&
parent[peer] !== undefined) {
present.push(peer);
}
}
if (present.length === 1) {
return value;
}
const context = { peers, peersWithLabels: internals.keysToLabels(this, peers) };
if (present.length === 0) {
return this.createError('object.missing', context, state, options);
}
return this.createError('object.xor', context, state, options);
};
internals.or = function (value, peers, parent, state, options) {
for (let i = 0; i < peers.length; ++i) {
const peer = peers[i];
if (Object.prototype.hasOwnProperty.call(parent, peer) &&
parent[peer] !== undefined) {
return value;
}
}
return this.createError('object.missing', {
peers,
peersWithLabels: internals.keysToLabels(this, peers)
}, state, options);
};
internals.and = function (value, peers, parent, state, options) {
const missing = [];
const present = [];
const count = peers.length;
for (let i = 0; i < count; ++i) {
const peer = peers[i];
if (!Object.prototype.hasOwnProperty.call(parent, peer) ||
parent[peer] === 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 (value, peers, parent, state, options) {
const present = [];
for (let i = 0; i < peers.length; ++i) {
const peer = peers[i];
if (Object.prototype.hasOwnProperty.call(parent, peer) &&
parent[peer] !== undefined) {
present.push(peer);
}
}
const values = Hoek.clone(peers);
const main = values.splice(0, 1)[0];
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();

632
node_modules/joi/lib/types/string/index.js generated vendored Executable file
View File

@ -0,0 +1,632 @@
'use strict';
// Load modules
const Net = require('net');
const Hoek = require('hoek');
let Isemail; // Loaded on demand
const Any = require('../any');
const Ref = require('../../ref');
const JoiDate = require('../date');
const Uri = require('./uri');
const Ip = require('./ip');
// Declare internals
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;
}
}
}
}
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');
const patternObject = {
pattern: new RegExp(pattern.source, pattern.ignoreCase ? 'i' : undefined) // Future version should break this and forbid unsupported regex flags
};
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(isEmailOptions) {
if (isEmailOptions) {
Hoek.assert(typeof isEmailOptions === 'object', 'email options must be an object');
Hoek.assert(typeof isEmailOptions.checkDNS === 'undefined', 'checkDNS option is not supported');
Hoek.assert(typeof isEmailOptions.tldWhitelist === 'undefined' ||
typeof isEmailOptions.tldWhitelist === 'object', 'tldWhitelist must be an array or object');
Hoek.assert(
typeof isEmailOptions.minDomainAtoms === 'undefined' ||
Number.isSafeInteger(isEmailOptions.minDomainAtoms) &&
isEmailOptions.minDomainAtoms > 0,
'minDomainAtoms must be a positive integer'
);
Hoek.assert(
typeof isEmailOptions.errorLevel === 'undefined' ||
typeof isEmailOptions.errorLevel === 'boolean' ||
(
Number.isSafeInteger(isEmailOptions.errorLevel) &&
isEmailOptions.errorLevel >= 0
),
'errorLevel must be a non-negative integer or boolean'
);
}
return this._test('email', isEmailOptions, function (value, state, options) {
Isemail = Isemail || require('isemail');
try {
const result = Isemail.validate(value, isEmailOptions);
if (result === true || result === 0) {
return value;
}
}
catch (e) { }
return this.createError('string.email', { value }, state, options);
});
}
ip(ipOptions) {
let regex = internals.ipRegex;
ipOptions = ipOptions || {};
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 = Hoek.unique(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 regex = internals.uriRegex;
if (uriOptions) {
Hoek.assert(typeof uriOptions === 'object', 'options must be an object');
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 (customScheme || allowRelative || relativeOnly) {
regex = Uri.createUriRegex(customScheme, allowRelative, relativeOnly);
}
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() {
const regex = /^[a-f0-9]+$/i;
return this._test('hex', regex, function (value, state, options) {
if (regex.test(value)) {
return value;
}
return this.createError('string.hex', { value }, state, options);
});
}
base64(base64Options) {
base64Options = 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+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/
// Padding is optional.
: /^(?:[A-Za-z0-9+\/]{4})*(?:[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);
});
}
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) {
form = 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() {
const 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);
});
obj._flags.trim = true;
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.key }, 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();

54
node_modules/joi/lib/types/string/ip.js generated vendored Normal file
View File

@ -0,0 +1,54 @@
'use strict';
// Load modules
const RFC3986 = require('./rfc3986');
// Declare internals
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;

209
node_modules/joi/lib/types/string/rfc3986.js generated vendored Normal file
View File

@ -0,0 +1,209 @@
'use strict';
// Load modules
// Delcare internals
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 + ']';
/**
* 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.
/**
* fragment = *( pchar / "/" / "?" )
*/
internals.rfc3986.fragment = '[' + pchar + '\\/\\?]*';
};
internals.generate();
module.exports = internals.rfc3986;

46
node_modules/joi/lib/types/string/uri.js generated vendored Normal file
View File

@ -0,0 +1,46 @@
'use strict';
// Load Modules
const RFC3986 = require('./rfc3986');
// Declare internals
const internals = {
Uri: {
createUriRegex: function (optionalScheme, allowRelative, relativeOnly) {
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 + '(?:\\?' + RFC3986.query + ')?' + '(?:#' + RFC3986.fragment + ')?$');
}
}
};
module.exports = internals.Uri;