This commit is contained in:
2023-08-11 10:45:20 +08:00
commit 161ca982f3
31850 changed files with 2706500 additions and 0 deletions

11
node_modules/joi/LICENSE.md generated vendored Normal file
View File

@ -0,0 +1,11 @@
Copyright (c) 2012-2022, Project contributors.
Copyright (c) 2012-2022, Sideway. Inc.
Copyright (c) 2012-2014, Walmart.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* The names of any contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

15
node_modules/joi/README.md generated vendored Normal file
View File

@ -0,0 +1,15 @@
# joi
#### The most powerful schema description language and data validator for JavaScript.
## Installation
`npm install joi`
### Visit the [joi.dev](https://joi.dev) Developer Portal for tutorials, documentation, and support
## Useful resources
- [Documentation and API](https://joi.dev/api/)
- [Versions status](https://joi.dev/resources/status/#joi)
- [Changelog](https://joi.dev/resources/changelog/)
- [Project policies](https://joi.dev/policies/)

1
node_modules/joi/dist/joi-browser.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long

175
node_modules/joi/lib/annotate.js generated vendored Normal file
View File

@ -0,0 +1,175 @@
'use strict';
const Clone = require('@hapi/hoek/lib/clone');
const Common = require('./common');
const internals = {
annotations: Symbol('annotations')
};
exports.error = function (stripColorCodes) {
if (!this._original ||
typeof this._original !== 'object') {
return this.details[0].message;
}
const redFgEscape = stripColorCodes ? '' : '\u001b[31m';
const redBgEscape = stripColorCodes ? '' : '\u001b[41m';
const endColor = stripColorCodes ? '' : '\u001b[0m';
const obj = Clone(this._original);
for (let i = this.details.length - 1; i >= 0; --i) { // Reverse order to process deepest child first
const pos = i + 1;
const error = this.details[i];
const path = error.path;
let node = obj;
for (let j = 0; ; ++j) {
const seg = path[j];
if (Common.isSchema(node)) {
node = node.clone(); // joi schemas are not cloned by hoek, we have to take this extra step
}
if (j + 1 < path.length &&
typeof node[seg] !== 'string') {
node = node[seg];
}
else {
const refAnnotations = node[internals.annotations] || { errors: {}, missing: {} };
node[internals.annotations] = refAnnotations;
const cacheKey = seg || error.context.key;
if (node[seg] !== 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;
};
// 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 {
for (const errorKey in annotations.errors) {
value[`${errorKey}_$key$_${annotations.errors[errorKey].sort().join(', ')}_$end$_`] = value[errorKey];
value[errorKey] = undefined;
}
for (const missingKey in annotations.missing) {
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;
};
};

1069
node_modules/joi/lib/base.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

143
node_modules/joi/lib/cache.js generated vendored Normal file
View File

@ -0,0 +1,143 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Clone = require('@hapi/hoek/lib/clone');
const Common = require('./common');
const internals = {
max: 1000,
supported: new Set(['undefined', 'boolean', 'number', 'string'])
};
exports.provider = {
provision(options) {
return new internals.Cache(options);
}
};
// Least Recently Used (LRU) Cache
internals.Cache = class {
constructor(options = {}) {
Common.assertOptions(options, ['max']);
Assert(options.max === undefined || options.max && options.max > 0 && isFinite(options.max), 'Invalid max cache size');
this._max = options.max || internals.max;
this._map = new Map(); // Map of nodes by key
this._list = new internals.List(); // List of nodes (most recently used in head)
}
get length() {
return this._map.size;
}
set(key, value) {
if (key !== null &&
!internals.supported.has(typeof key)) {
return;
}
let node = this._map.get(key);
if (node) {
node.value = value;
this._list.first(node);
return;
}
node = this._list.unshift({ key, value });
this._map.set(key, node);
this._compact();
}
get(key) {
const node = this._map.get(key);
if (node) {
this._list.first(node);
return Clone(node.value);
}
}
_compact() {
if (this._map.size > this._max) {
const node = this._list.pop();
this._map.delete(node.key);
}
}
};
internals.List = class {
constructor() {
this.tail = null;
this.head = null;
}
unshift(node) {
node.next = null;
node.prev = this.head;
if (this.head) {
this.head.next = node;
}
this.head = node;
if (!this.tail) {
this.tail = node;
}
return node;
}
first(node) {
if (node === this.head) {
return;
}
this._remove(node);
this.unshift(node);
}
pop() {
return this._remove(this.tail);
}
_remove(node) {
const { next, prev } = node;
next.prev = prev;
if (prev) {
prev.next = next;
}
if (node === this.tail) {
this.tail = next;
}
node.prev = null;
node.next = null;
return node;
}
};

216
node_modules/joi/lib/common.js generated vendored Normal file
View File

@ -0,0 +1,216 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const AssertError = require('@hapi/hoek/lib/error');
const Pkg = require('../package.json');
let Messages;
let Schemas;
const 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)?)?)?)?$/
};
exports.version = Pkg.version;
exports.defaults = {
abortEarly: true,
allowUnknown: false,
artifacts: false,
cache: true,
context: null,
convert: true,
dateFormat: 'iso',
errors: {
escapeHtml: false,
label: 'path',
language: null,
render: true,
stack: false,
wrap: {
label: '"',
array: '[]'
}
},
externals: true,
messages: {},
nonEnumerables: false,
noDefaults: false,
presence: 'optional',
skipFunctions: false,
stripUnknown: false,
warnings: false
};
exports.symbols = {
any: Symbol.for('@hapi/joi/schema'), // Used to internally identify any-based types (shared with other joi versions)
arraySingle: Symbol('arraySingle'),
deepDefault: Symbol('deepDefault'),
errors: Symbol('errors'),
literal: Symbol('literal'),
override: Symbol('override'),
parent: Symbol('parent'),
prefs: Symbol('prefs'),
ref: Symbol('ref'),
template: Symbol('template'),
values: Symbol('values')
};
exports.assertOptions = function (options, keys, name = 'Options') {
Assert(options && typeof options === 'object' && !Array.isArray(options), 'Options must be of type object');
const unknownKeys = Object.keys(options).filter((k) => !keys.includes(k));
Assert(unknownKeys.length === 0, `${name} contain unknown keys: ${unknownKeys}`);
};
exports.checkPreferences = function (prefs) {
Schemas = Schemas || require('./schemas');
const result = Schemas.preferences.validate(prefs);
if (result.error) {
throw new AssertError([result.error.details[0].message]);
}
};
exports.compare = function (a, b, operator) {
switch (operator) {
case '=': return a === b;
case '>': return a > b;
case '<': return a < b;
case '>=': return a >= b;
case '<=': return a <= b;
}
};
exports.default = function (value, defaultValue) {
return value === undefined ? defaultValue : value;
};
exports.isIsoDate = function (date) {
return internals.isoDate.test(date);
};
exports.isNumber = function (value) {
return typeof value === 'number' && !isNaN(value);
};
exports.isResolvable = function (obj) {
if (!obj) {
return false;
}
return obj[exports.symbols.ref] || obj[exports.symbols.template];
};
exports.isSchema = function (schema, options = {}) {
const any = schema && schema[exports.symbols.any];
if (!any) {
return false;
}
Assert(options.legacy || any.version === exports.version, 'Cannot mix different versions of joi schemas');
return true;
};
exports.isValues = function (obj) {
return obj[exports.symbols.values];
};
exports.limit = function (value) {
return Number.isSafeInteger(value) && value >= 0;
};
exports.preferences = function (target, source) {
Messages = Messages || require('./messages');
target = target || {};
source = source || {};
const merged = Object.assign({}, target, source);
if (source.errors &&
target.errors) {
merged.errors = Object.assign({}, target.errors, source.errors);
merged.errors.wrap = Object.assign({}, target.errors.wrap, source.errors.wrap);
}
if (source.messages) {
merged.messages = Messages.compile(source.messages, target.messages);
}
delete merged[exports.symbols.prefs];
return merged;
};
exports.tryWithPath = function (fn, key, options = {}) {
try {
return fn();
}
catch (err) {
if (err.path !== undefined) {
err.path = key + '.' + err.path;
}
else {
err.path = key;
}
if (options.append) {
err.message = `${err.message} (${err.path})`;
}
throw err;
}
};
exports.validateArg = function (value, label, { assert, message }) {
if (exports.isSchema(assert)) {
const result = assert.validate(value);
if (!result.error) {
return;
}
return result.error.message;
}
else if (!assert(value)) {
return label ? `${label} ${message}` : message;
}
};
exports.verifyFlat = function (args, method) {
for (const arg of args) {
Assert(!Array.isArray(arg), 'Method no longer accepts array arguments:', method);
}
};

283
node_modules/joi/lib/compile.js generated vendored Normal file
View File

@ -0,0 +1,283 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Common = require('./common');
const Ref = require('./ref');
const internals = {};
exports.schema = function (Joi, config, options = {}) {
Common.assertOptions(options, ['appendPath', 'override']);
try {
return internals.schema(Joi, config, options);
}
catch (err) {
if (options.appendPath &&
err.path !== undefined) {
err.message = `${err.message} (${err.path})`;
}
throw err;
}
};
internals.schema = function (Joi, config, options) {
Assert(config !== undefined, 'Invalid undefined schema');
if (Array.isArray(config)) {
Assert(config.length, 'Invalid empty array schema');
if (config.length === 1) {
config = config[0];
}
}
const valid = (base, ...values) => {
if (options.override !== false) {
return base.valid(Joi.override, ...values);
}
return base.valid(...values);
};
if (internals.simple(config)) {
return valid(Joi, config);
}
if (typeof config === 'function') {
return Joi.custom(config);
}
Assert(typeof config === 'object', 'Invalid schema content:', typeof config);
if (Common.isResolvable(config)) {
return valid(Joi, config);
}
if (Common.isSchema(config)) {
return config;
}
if (Array.isArray(config)) {
for (const item of config) {
if (!internals.simple(item)) {
return Joi.alternatives().try(...config);
}
}
return valid(Joi, ...config);
}
if (config instanceof RegExp) {
return Joi.string().regex(config);
}
if (config instanceof Date) {
return valid(Joi.date(), config);
}
Assert(Object.getPrototypeOf(config) === Object.getPrototypeOf({}), 'Schema can only contain plain objects');
return Joi.object().keys(config);
};
exports.ref = function (id, options) {
return Ref.isRef(id) ? id : Ref.create(id, options);
};
exports.compile = function (root, schema, options = {}) {
Common.assertOptions(options, ['legacy']);
// Compiled by any supported version
const any = schema && schema[Common.symbols.any];
if (any) {
Assert(options.legacy || any.version === Common.version, 'Cannot mix different versions of joi schemas:', any.version, Common.version);
return schema;
}
// Uncompiled root
if (typeof schema !== 'object' ||
!options.legacy) {
return exports.schema(root, schema, { appendPath: true }); // Will error if schema contains other versions
}
// Scan schema for compiled parts
const compiler = internals.walk(schema);
if (!compiler) {
return exports.schema(root, schema, { appendPath: true });
}
return compiler.compile(compiler.root, schema);
};
internals.walk = function (schema) {
if (typeof schema !== 'object') {
return null;
}
if (Array.isArray(schema)) {
for (const item of schema) {
const compiler = internals.walk(item);
if (compiler) {
return compiler;
}
}
return null;
}
const any = schema[Common.symbols.any];
if (any) {
return { root: schema[any.root], compile: any.compile };
}
Assert(Object.getPrototypeOf(schema) === Object.getPrototypeOf({}), 'Schema can only contain plain objects');
for (const key in schema) {
const compiler = internals.walk(schema[key]);
if (compiler) {
return compiler;
}
}
return null;
};
internals.simple = function (value) {
return value === null || ['boolean', 'string', 'number'].includes(typeof value);
};
exports.when = function (schema, condition, options) {
if (options === undefined) {
Assert(condition && typeof condition === 'object', 'Missing options');
options = condition;
condition = Ref.create('.');
}
if (Array.isArray(options)) {
options = { switch: options };
}
Common.assertOptions(options, ['is', 'not', 'then', 'otherwise', 'switch', 'break']);
// Schema condition
if (Common.isSchema(condition)) {
Assert(options.is === undefined, '"is" can not be used with a schema condition');
Assert(options.not === undefined, '"not" can not be used with a schema condition');
Assert(options.switch === undefined, '"switch" can not be used with a schema condition');
return internals.condition(schema, { is: condition, then: options.then, otherwise: options.otherwise, break: options.break });
}
// Single condition
Assert(Ref.isRef(condition) || typeof condition === 'string', 'Invalid condition:', condition);
Assert(options.not === undefined || options.is === undefined, 'Cannot combine "is" with "not"');
if (options.switch === undefined) {
let rule = options;
if (options.not !== undefined) {
rule = { is: options.not, then: options.otherwise, otherwise: options.then, break: options.break };
}
let is = rule.is !== undefined ? schema.$_compile(rule.is) : schema.$_root.invalid(null, false, 0, '').required();
Assert(rule.then !== undefined || rule.otherwise !== undefined, 'options must have at least one of "then", "otherwise", or "switch"');
Assert(rule.break === undefined || rule.then === undefined || rule.otherwise === undefined, 'Cannot specify then, otherwise, and break all together');
if (options.is !== undefined &&
!Ref.isRef(options.is) &&
!Common.isSchema(options.is)) {
is = is.required(); // Only apply required if this wasn't already a schema or a ref
}
return internals.condition(schema, { ref: exports.ref(condition), is, then: rule.then, otherwise: rule.otherwise, break: rule.break });
}
// Switch statement
Assert(Array.isArray(options.switch), '"switch" must be an array');
Assert(options.is === undefined, 'Cannot combine "switch" with "is"');
Assert(options.not === undefined, 'Cannot combine "switch" with "not"');
Assert(options.then === undefined, 'Cannot combine "switch" with "then"');
const rule = {
ref: exports.ref(condition),
switch: [],
break: options.break
};
for (let i = 0; i < options.switch.length; ++i) {
const test = options.switch[i];
const last = i === options.switch.length - 1;
Common.assertOptions(test, last ? ['is', 'then', 'otherwise'] : ['is', 'then']);
Assert(test.is !== undefined, 'Switch statement missing "is"');
Assert(test.then !== undefined, 'Switch statement missing "then"');
const item = {
is: schema.$_compile(test.is),
then: schema.$_compile(test.then)
};
if (!Ref.isRef(test.is) &&
!Common.isSchema(test.is)) {
item.is = item.is.required(); // Only apply required if this wasn't already a schema or a ref
}
if (last) {
Assert(options.otherwise === undefined || test.otherwise === undefined, 'Cannot specify "otherwise" inside and outside a "switch"');
const otherwise = options.otherwise !== undefined ? options.otherwise : test.otherwise;
if (otherwise !== undefined) {
Assert(rule.break === undefined, 'Cannot specify both otherwise and break');
item.otherwise = schema.$_compile(otherwise);
}
}
rule.switch.push(item);
}
return rule;
};
internals.condition = function (schema, condition) {
for (const key of ['then', 'otherwise']) {
if (condition[key] === undefined) {
delete condition[key];
}
else {
condition[key] = schema.$_compile(condition[key]);
}
}
return condition;
};

271
node_modules/joi/lib/errors.js generated vendored Normal file
View File

@ -0,0 +1,271 @@
'use strict';
const Annotate = require('./annotate');
const Common = require('./common');
const Template = require('./template');
const internals = {};
exports.Report = class {
constructor(code, value, local, flags, messages, state, prefs) {
this.code = code;
this.flags = flags;
this.messages = messages;
this.path = state.path;
this.prefs = prefs;
this.state = state;
this.value = value;
this.message = null;
this.template = null;
this.local = local || {};
this.local.label = exports.label(this.flags, this.state, this.prefs, this.messages);
if (this.value !== undefined &&
!this.local.hasOwnProperty('value')) {
this.local.value = this.value;
}
if (this.path.length) {
const key = this.path[this.path.length - 1];
if (typeof key !== 'object') {
this.local.key = key;
}
}
}
_setTemplate(template) {
this.template = template;
if (!this.flags.label &&
this.path.length === 0) {
const localized = this._template(this.template, 'root');
if (localized) {
this.local.label = localized;
}
}
}
toString() {
if (this.message) {
return this.message;
}
const code = this.code;
if (!this.prefs.errors.render) {
return this.code;
}
const template = this._template(this.template) ||
this._template(this.prefs.messages) ||
this._template(this.messages);
if (template === undefined) {
return `Error code "${code}" is not defined, your custom type is missing the correct messages definition`;
}
// Render and cache result
this.message = template.render(this.value, this.state, this.prefs, this.local, { errors: this.prefs.errors, messages: [this.prefs.messages, this.messages] });
if (!this.prefs.errors.label) {
this.message = this.message.replace(/^"" /, '').trim();
}
return this.message;
}
_template(messages, code) {
return exports.template(this.value, messages, code || this.code, this.state, this.prefs);
}
};
exports.path = function (path) {
let label = '';
for (const segment of path) {
if (typeof segment === 'object') { // Exclude array single path segment
continue;
}
if (typeof segment === 'string') {
if (label) {
label += '.';
}
label += segment;
}
else {
label += `[${segment}]`;
}
}
return label;
};
exports.template = function (value, messages, code, state, prefs) {
if (!messages) {
return;
}
if (Template.isTemplate(messages)) {
return code !== 'root' ? messages : null;
}
let lang = prefs.errors.language;
if (Common.isResolvable(lang)) {
lang = lang.resolve(value, state, prefs);
}
if (lang &&
messages[lang]) {
if (messages[lang][code] !== undefined) {
return messages[lang][code];
}
if (messages[lang]['*'] !== undefined) {
return messages[lang]['*'];
}
}
if (!messages[code]) {
return messages['*'];
}
return messages[code];
};
exports.label = function (flags, state, prefs, messages) {
if (flags.label) {
return flags.label;
}
if (!prefs.errors.label) {
return '';
}
let path = state.path;
if (prefs.errors.label === 'key' &&
state.path.length > 1) {
path = state.path.slice(-1);
}
const normalized = exports.path(path);
if (normalized) {
return normalized;
}
return exports.template(null, prefs.messages, 'root', state, prefs) ||
messages && exports.template(null, messages, 'root', state, prefs) ||
'value';
};
exports.process = function (errors, original, prefs) {
if (!errors) {
return null;
}
const { override, message, details } = exports.details(errors);
if (override) {
return override;
}
if (prefs.errors.stack) {
return new exports.ValidationError(message, details, original);
}
const limit = Error.stackTraceLimit;
Error.stackTraceLimit = 0;
const validationError = new exports.ValidationError(message, details, original);
Error.stackTraceLimit = limit;
return validationError;
};
exports.details = function (errors, options = {}) {
let messages = [];
const details = [];
for (const item of errors) {
// Override
if (item instanceof Error) {
if (options.override !== false) {
return { override: item };
}
const message = item.toString();
messages.push(message);
details.push({
message,
type: 'override',
context: { error: item }
});
continue;
}
// Report
const message = item.toString();
messages.push(message);
details.push({
message,
path: item.path.filter((v) => typeof v !== 'object'),
type: item.code,
context: item.local
});
}
if (messages.length > 1) {
messages = [...new Set(messages)];
}
return { message: messages.join('. '), details };
};
exports.ValidationError = class extends Error {
constructor(message, details, original) {
super(message);
this._original = original;
this.details = details;
}
static isError(err) {
return err instanceof exports.ValidationError;
}
};
exports.ValidationError.prototype.isJoi = true;
exports.ValidationError.prototype.name = 'ValidationError';
exports.ValidationError.prototype.annotate = Annotate.error;

312
node_modules/joi/lib/extend.js generated vendored Normal file
View File

@ -0,0 +1,312 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Clone = require('@hapi/hoek/lib/clone');
const Common = require('./common');
const Messages = require('./messages');
const internals = {};
exports.type = function (from, options) {
const base = Object.getPrototypeOf(from);
const prototype = Clone(base);
const schema = from._assign(Object.create(prototype));
const def = Object.assign({}, options); // Shallow cloned
delete def.base;
prototype._definition = def;
const parent = base._definition || {};
def.messages = Messages.merge(parent.messages, def.messages);
def.properties = Object.assign({}, parent.properties, def.properties);
// Type
schema.type = def.type;
// Flags
def.flags = Object.assign({}, parent.flags, def.flags);
// Terms
const terms = Object.assign({}, parent.terms);
if (def.terms) {
for (const name in def.terms) { // Only apply own terms
const term = def.terms[name];
Assert(schema.$_terms[name] === undefined, 'Invalid term override for', def.type, name);
schema.$_terms[name] = term.init;
terms[name] = term;
}
}
def.terms = terms;
// Constructor arguments
if (!def.args) {
def.args = parent.args;
}
// Prepare
def.prepare = internals.prepare(def.prepare, parent.prepare);
// Coerce
if (def.coerce) {
if (typeof def.coerce === 'function') {
def.coerce = { method: def.coerce };
}
if (def.coerce.from &&
!Array.isArray(def.coerce.from)) {
def.coerce = { method: def.coerce.method, from: [].concat(def.coerce.from) };
}
}
def.coerce = internals.coerce(def.coerce, parent.coerce);
// Validate
def.validate = internals.validate(def.validate, parent.validate);
// Rules
const rules = Object.assign({}, parent.rules);
if (def.rules) {
for (const name in def.rules) {
const rule = def.rules[name];
Assert(typeof rule === 'object', 'Invalid rule definition for', def.type, name);
let method = rule.method;
if (method === undefined) {
method = function () {
return this.$_addRule(name);
};
}
if (method) {
Assert(!prototype[name], 'Rule conflict in', def.type, name);
prototype[name] = method;
}
Assert(!rules[name], 'Rule conflict in', def.type, name);
rules[name] = rule;
if (rule.alias) {
const aliases = [].concat(rule.alias);
for (const alias of aliases) {
prototype[alias] = rule.method;
}
}
if (rule.args) {
rule.argsByName = new Map();
rule.args = rule.args.map((arg) => {
if (typeof arg === 'string') {
arg = { name: arg };
}
Assert(!rule.argsByName.has(arg.name), 'Duplicated argument name', arg.name);
if (Common.isSchema(arg.assert)) {
arg.assert = arg.assert.strict().label(arg.name);
}
rule.argsByName.set(arg.name, arg);
return arg;
});
}
}
}
def.rules = rules;
// Modifiers
const modifiers = Object.assign({}, parent.modifiers);
if (def.modifiers) {
for (const name in def.modifiers) {
Assert(!prototype[name], 'Rule conflict in', def.type, name);
const modifier = def.modifiers[name];
Assert(typeof modifier === 'function', 'Invalid modifier definition for', def.type, name);
const method = function (arg) {
return this.rule({ [name]: arg });
};
prototype[name] = method;
modifiers[name] = modifier;
}
}
def.modifiers = modifiers;
// Overrides
if (def.overrides) {
prototype._super = base;
schema.$_super = {}; // Backwards compatibility
for (const override in def.overrides) {
Assert(base[override], 'Cannot override missing', override);
def.overrides[override][Common.symbols.parent] = base[override];
schema.$_super[override] = base[override].bind(schema); // Backwards compatibility
}
Object.assign(prototype, def.overrides);
}
// Casts
def.cast = Object.assign({}, parent.cast, def.cast);
// Manifest
const manifest = Object.assign({}, parent.manifest, def.manifest);
manifest.build = internals.build(def.manifest && def.manifest.build, parent.manifest && parent.manifest.build);
def.manifest = manifest;
// Rebuild
def.rebuild = internals.rebuild(def.rebuild, parent.rebuild);
return schema;
};
// Helpers
internals.build = function (child, parent) {
if (!child ||
!parent) {
return child || parent;
}
return function (obj, desc) {
return parent(child(obj, desc), desc);
};
};
internals.coerce = function (child, parent) {
if (!child ||
!parent) {
return child || parent;
}
return {
from: child.from && parent.from ? [...new Set([...child.from, ...parent.from])] : null,
method(value, helpers) {
let coerced;
if (!parent.from ||
parent.from.includes(typeof value)) {
coerced = parent.method(value, helpers);
if (coerced) {
if (coerced.errors ||
coerced.value === undefined) {
return coerced;
}
value = coerced.value;
}
}
if (!child.from ||
child.from.includes(typeof value)) {
const own = child.method(value, helpers);
if (own) {
return own;
}
}
return coerced;
}
};
};
internals.prepare = function (child, parent) {
if (!child ||
!parent) {
return child || parent;
}
return function (value, helpers) {
const prepared = child(value, helpers);
if (prepared) {
if (prepared.errors ||
prepared.value === undefined) {
return prepared;
}
value = prepared.value;
}
return parent(value, helpers) || prepared;
};
};
internals.rebuild = function (child, parent) {
if (!child ||
!parent) {
return child || parent;
}
return function (schema) {
parent(schema);
child(schema);
};
};
internals.validate = function (child, parent) {
if (!child ||
!parent) {
return child || parent;
}
return function (value, helpers) {
const result = parent(value, helpers);
if (result) {
if (result.errors &&
(!Array.isArray(result.errors) || result.errors.length)) {
return result;
}
value = result.value;
}
return child(value, helpers) || result;
};
};

2348
node_modules/joi/lib/index.d.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

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

@ -0,0 +1,283 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Clone = require('@hapi/hoek/lib/clone');
const Cache = require('./cache');
const Common = require('./common');
const Compile = require('./compile');
const Errors = require('./errors');
const Extend = require('./extend');
const Manifest = require('./manifest');
const Ref = require('./ref');
const Template = require('./template');
const Trace = require('./trace');
let Schemas;
const internals = {
types: {
alternatives: require('./types/alternatives'),
any: require('./types/any'),
array: require('./types/array'),
boolean: require('./types/boolean'),
date: require('./types/date'),
function: require('./types/function'),
link: require('./types/link'),
number: require('./types/number'),
object: require('./types/object'),
string: require('./types/string'),
symbol: require('./types/symbol')
},
aliases: {
alt: 'alternatives',
bool: 'boolean',
func: 'function'
}
};
if (Buffer) { // $lab:coverage:ignore$
internals.types.binary = require('./types/binary');
}
internals.root = function () {
const root = {
_types: new Set(Object.keys(internals.types))
};
// Types
for (const type of root._types) {
root[type] = function (...args) {
Assert(!args.length || ['alternatives', 'link', 'object'].includes(type), 'The', type, 'type does not allow arguments');
return internals.generate(this, internals.types[type], args);
};
}
// Shortcuts
for (const method of ['allow', 'custom', 'disallow', 'equal', 'exist', 'forbidden', 'invalid', 'not', 'only', 'optional', 'options', 'prefs', 'preferences', 'required', 'strip', 'valid', 'when']) {
root[method] = function (...args) {
return this.any()[method](...args);
};
}
// Methods
Object.assign(root, internals.methods);
// Aliases
for (const alias in internals.aliases) {
const target = internals.aliases[alias];
root[alias] = root[target];
}
root.x = root.expression;
// Trace
if (Trace.setup) { // $lab:coverage:ignore$
Trace.setup(root);
}
return root;
};
internals.methods = {
ValidationError: Errors.ValidationError,
version: Common.version,
cache: Cache.provider,
assert(value, schema, ...args /* [message], [options] */) {
internals.assert(value, schema, true, args);
},
attempt(value, schema, ...args /* [message], [options] */) {
return internals.assert(value, schema, false, args);
},
build(desc) {
Assert(typeof Manifest.build === 'function', 'Manifest functionality disabled');
return Manifest.build(this, desc);
},
checkPreferences(prefs) {
Common.checkPreferences(prefs);
},
compile(schema, options) {
return Compile.compile(this, schema, options);
},
defaults(modifier) {
Assert(typeof modifier === 'function', 'modifier must be a function');
const joi = Object.assign({}, this);
for (const type of joi._types) {
const schema = modifier(joi[type]());
Assert(Common.isSchema(schema), 'modifier must return a valid schema object');
joi[type] = function (...args) {
return internals.generate(this, schema, args);
};
}
return joi;
},
expression(...args) {
return new Template(...args);
},
extend(...extensions) {
Common.verifyFlat(extensions, 'extend');
Schemas = Schemas || require('./schemas');
Assert(extensions.length, 'You need to provide at least one extension');
this.assert(extensions, Schemas.extensions);
const joi = Object.assign({}, this);
joi._types = new Set(joi._types);
for (let extension of extensions) {
if (typeof extension === 'function') {
extension = extension(joi);
}
this.assert(extension, Schemas.extension);
const expanded = internals.expandExtension(extension, joi);
for (const item of expanded) {
Assert(joi[item.type] === undefined || joi._types.has(item.type), 'Cannot override name', item.type);
const base = item.base || this.any();
const schema = Extend.type(base, item);
joi._types.add(item.type);
joi[item.type] = function (...args) {
return internals.generate(this, schema, args);
};
}
}
return joi;
},
isError: Errors.ValidationError.isError,
isExpression: Template.isTemplate,
isRef: Ref.isRef,
isSchema: Common.isSchema,
in(...args) {
return Ref.in(...args);
},
override: Common.symbols.override,
ref(...args) {
return Ref.create(...args);
},
types() {
const types = {};
for (const type of this._types) {
types[type] = this[type]();
}
for (const target in internals.aliases) {
types[target] = this[target]();
}
return types;
}
};
// Helpers
internals.assert = function (value, schema, annotate, args /* [message], [options] */) {
const message = args[0] instanceof Error || typeof args[0] === 'string' ? args[0] : null;
const options = message !== null ? args[1] : args[0];
const result = schema.validate(value, Common.preferences({ errors: { stack: true } }, options || {}));
let error = result.error;
if (!error) {
return result.value;
}
if (message instanceof Error) {
throw message;
}
const display = annotate && typeof error.annotate === 'function' ? error.annotate() : error.message;
if (error instanceof Errors.ValidationError === false) {
error = Clone(error);
}
error.message = message ? `${message} ${display}` : display;
throw error;
};
internals.generate = function (root, schema, args) {
Assert(root, 'Must be invoked on a Joi instance.');
schema.$_root = root;
if (!schema._definition.args ||
!args.length) {
return schema;
}
return schema._definition.args(schema, ...args);
};
internals.expandExtension = function (extension, joi) {
if (typeof extension.type === 'string') {
return [extension];
}
const extended = [];
for (const type of joi._types) {
if (extension.type.test(type)) {
const item = Object.assign({}, extension);
item.type = type;
item.base = joi[type]();
extended.push(item);
}
}
return extended;
};
module.exports = internals.root();

476
node_modules/joi/lib/manifest.js generated vendored Normal file
View File

@ -0,0 +1,476 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Clone = require('@hapi/hoek/lib/clone');
const Common = require('./common');
const Messages = require('./messages');
const Ref = require('./ref');
const Template = require('./template');
let Schemas;
const internals = {};
exports.describe = function (schema) {
const def = schema._definition;
// Type
const desc = {
type: schema.type,
flags: {},
rules: []
};
// Flags
for (const flag in schema._flags) {
if (flag[0] !== '_') {
desc.flags[flag] = internals.describe(schema._flags[flag]);
}
}
if (!Object.keys(desc.flags).length) {
delete desc.flags;
}
// Preferences
if (schema._preferences) {
desc.preferences = Clone(schema._preferences, { shallow: ['messages'] });
delete desc.preferences[Common.symbols.prefs];
if (desc.preferences.messages) {
desc.preferences.messages = Messages.decompile(desc.preferences.messages);
}
}
// Allow / Invalid
if (schema._valids) {
desc.allow = schema._valids.describe();
}
if (schema._invalids) {
desc.invalid = schema._invalids.describe();
}
// Rules
for (const rule of schema._rules) {
const ruleDef = def.rules[rule.name];
if (ruleDef.manifest === false) { // Defaults to true
continue;
}
const item = { name: rule.name };
for (const custom in def.modifiers) {
if (rule[custom] !== undefined) {
item[custom] = internals.describe(rule[custom]);
}
}
if (rule.args) {
item.args = {};
for (const key in rule.args) {
const arg = rule.args[key];
if (key === 'options' &&
!Object.keys(arg).length) {
continue;
}
item.args[key] = internals.describe(arg, { assign: key });
}
if (!Object.keys(item.args).length) {
delete item.args;
}
}
desc.rules.push(item);
}
if (!desc.rules.length) {
delete desc.rules;
}
// Terms (must be last to verify no name conflicts)
for (const term in schema.$_terms) {
if (term[0] === '_') {
continue;
}
Assert(!desc[term], 'Cannot describe schema due to internal name conflict with', term);
const items = schema.$_terms[term];
if (!items) {
continue;
}
if (items instanceof Map) {
if (items.size) {
desc[term] = [...items.entries()];
}
continue;
}
if (Common.isValues(items)) {
desc[term] = items.describe();
continue;
}
Assert(def.terms[term], 'Term', term, 'missing configuration');
const manifest = def.terms[term].manifest;
const mapped = typeof manifest === 'object';
if (!items.length &&
!mapped) {
continue;
}
const normalized = [];
for (const item of items) {
normalized.push(internals.describe(item));
}
// Mapped
if (mapped) {
const { from, to } = manifest.mapped;
desc[term] = {};
for (const item of normalized) {
desc[term][item[to]] = item[from];
}
continue;
}
// Single
if (manifest === 'single') {
Assert(normalized.length === 1, 'Term', term, 'contains more than one item');
desc[term] = normalized[0];
continue;
}
// Array
desc[term] = normalized;
}
internals.validate(schema.$_root, desc);
return desc;
};
internals.describe = function (item, options = {}) {
if (Array.isArray(item)) {
return item.map(internals.describe);
}
if (item === Common.symbols.deepDefault) {
return { special: 'deep' };
}
if (typeof item !== 'object' ||
item === null) {
return item;
}
if (options.assign === 'options') {
return Clone(item);
}
if (Buffer && Buffer.isBuffer(item)) { // $lab:coverage:ignore$
return { buffer: item.toString('binary') };
}
if (item instanceof Date) {
return item.toISOString();
}
if (item instanceof Error) {
return item;
}
if (item instanceof RegExp) {
if (options.assign === 'regex') {
return item.toString();
}
return { regex: item.toString() };
}
if (item[Common.symbols.literal]) {
return { function: item.literal };
}
if (typeof item.describe === 'function') {
if (options.assign === 'ref') {
return item.describe().ref;
}
return item.describe();
}
const normalized = {};
for (const key in item) {
const value = item[key];
if (value === undefined) {
continue;
}
normalized[key] = internals.describe(value, { assign: key });
}
return normalized;
};
exports.build = function (joi, desc) {
const builder = new internals.Builder(joi);
return builder.parse(desc);
};
internals.Builder = class {
constructor(joi) {
this.joi = joi;
}
parse(desc) {
internals.validate(this.joi, desc);
// Type
let schema = this.joi[desc.type]()._bare();
const def = schema._definition;
// Flags
if (desc.flags) {
for (const flag in desc.flags) {
const setter = def.flags[flag] && def.flags[flag].setter || flag;
Assert(typeof schema[setter] === 'function', 'Invalid flag', flag, 'for type', desc.type);
schema = schema[setter](this.build(desc.flags[flag]));
}
}
// Preferences
if (desc.preferences) {
schema = schema.preferences(this.build(desc.preferences));
}
// Allow / Invalid
if (desc.allow) {
schema = schema.allow(...this.build(desc.allow));
}
if (desc.invalid) {
schema = schema.invalid(...this.build(desc.invalid));
}
// Rules
if (desc.rules) {
for (const rule of desc.rules) {
Assert(typeof schema[rule.name] === 'function', 'Invalid rule', rule.name, 'for type', desc.type);
const args = [];
if (rule.args) {
const built = {};
for (const key in rule.args) {
built[key] = this.build(rule.args[key], { assign: key });
}
const keys = Object.keys(built);
const definition = def.rules[rule.name].args;
if (definition) {
Assert(keys.length <= definition.length, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to', definition.length, ', found', keys.length, ')');
for (const { name } of definition) {
args.push(built[name]);
}
}
else {
Assert(keys.length === 1, 'Invalid number of arguments for', desc.type, rule.name, '(expected up to 1, found', keys.length, ')');
args.push(built[keys[0]]);
}
}
// Apply
schema = schema[rule.name](...args);
// Ruleset
const options = {};
for (const custom in def.modifiers) {
if (rule[custom] !== undefined) {
options[custom] = this.build(rule[custom]);
}
}
if (Object.keys(options).length) {
schema = schema.rule(options);
}
}
}
// Terms
const terms = {};
for (const key in desc) {
if (['allow', 'flags', 'invalid', 'whens', 'preferences', 'rules', 'type'].includes(key)) {
continue;
}
Assert(def.terms[key], 'Term', key, 'missing configuration');
const manifest = def.terms[key].manifest;
if (manifest === 'schema') {
terms[key] = desc[key].map((item) => this.parse(item));
continue;
}
if (manifest === 'values') {
terms[key] = desc[key].map((item) => this.build(item));
continue;
}
if (manifest === 'single') {
terms[key] = this.build(desc[key]);
continue;
}
if (typeof manifest === 'object') {
terms[key] = {};
for (const name in desc[key]) {
const value = desc[key][name];
terms[key][name] = this.parse(value);
}
continue;
}
terms[key] = this.build(desc[key]);
}
if (desc.whens) {
terms.whens = desc.whens.map((when) => this.build(when));
}
schema = def.manifest.build(schema, terms);
schema.$_temp.ruleset = false;
return schema;
}
build(desc, options = {}) {
if (desc === null) {
return null;
}
if (Array.isArray(desc)) {
return desc.map((item) => this.build(item));
}
if (desc instanceof Error) {
return desc;
}
if (options.assign === 'options') {
return Clone(desc);
}
if (options.assign === 'regex') {
return internals.regex(desc);
}
if (options.assign === 'ref') {
return Ref.build(desc);
}
if (typeof desc !== 'object') {
return desc;
}
if (Object.keys(desc).length === 1) {
if (desc.buffer) {
Assert(Buffer, 'Buffers are not supported');
return Buffer && Buffer.from(desc.buffer, 'binary'); // $lab:coverage:ignore$
}
if (desc.function) {
return { [Common.symbols.literal]: true, literal: desc.function };
}
if (desc.override) {
return Common.symbols.override;
}
if (desc.ref) {
return Ref.build(desc.ref);
}
if (desc.regex) {
return internals.regex(desc.regex);
}
if (desc.special) {
Assert(['deep'].includes(desc.special), 'Unknown special value', desc.special);
return Common.symbols.deepDefault;
}
if (desc.value) {
return Clone(desc.value);
}
}
if (desc.type) {
return this.parse(desc);
}
if (desc.template) {
return Template.build(desc);
}
const normalized = {};
for (const key in desc) {
normalized[key] = this.build(desc[key], { assign: key });
}
return normalized;
}
};
internals.regex = function (string) {
const end = string.lastIndexOf('/');
const exp = string.slice(1, end);
const flags = string.slice(end + 1);
return new RegExp(exp, flags);
};
internals.validate = function (joi, desc) {
Schemas = Schemas || require('./schemas');
joi.assert(desc, Schemas.description);
};

178
node_modules/joi/lib/messages.js generated vendored Normal file
View File

@ -0,0 +1,178 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Clone = require('@hapi/hoek/lib/clone');
const Template = require('./template');
const internals = {};
exports.compile = function (messages, target) {
// Single value string ('plain error message', 'template {error} message')
if (typeof messages === 'string') {
Assert(!target, 'Cannot set single message string');
return new Template(messages);
}
// Single value template
if (Template.isTemplate(messages)) {
Assert(!target, 'Cannot set single message template');
return messages;
}
// By error code { 'number.min': <string | template> }
Assert(typeof messages === 'object' && !Array.isArray(messages), 'Invalid message options');
target = target ? Clone(target) : {};
for (let code in messages) {
const message = messages[code];
if (code === 'root' ||
Template.isTemplate(message)) {
target[code] = message;
continue;
}
if (typeof message === 'string') {
target[code] = new Template(message);
continue;
}
// By language { english: { 'number.min': <string | template> } }
Assert(typeof message === 'object' && !Array.isArray(message), 'Invalid message for', code);
const language = code;
target[language] = target[language] || {};
for (code in message) {
const localized = message[code];
if (code === 'root' ||
Template.isTemplate(localized)) {
target[language][code] = localized;
continue;
}
Assert(typeof localized === 'string', 'Invalid message for', code, 'in', language);
target[language][code] = new Template(localized);
}
}
return target;
};
exports.decompile = function (messages) {
// By error code { 'number.min': <string | template> }
const target = {};
for (let code in messages) {
const message = messages[code];
if (code === 'root') {
target.root = message;
continue;
}
if (Template.isTemplate(message)) {
target[code] = message.describe({ compact: true });
continue;
}
// By language { english: { 'number.min': <string | template> } }
const language = code;
target[language] = {};
for (code in message) {
const localized = message[code];
if (code === 'root') {
target[language].root = localized;
continue;
}
target[language][code] = localized.describe({ compact: true });
}
}
return target;
};
exports.merge = function (base, extended) {
if (!base) {
return exports.compile(extended);
}
if (!extended) {
return base;
}
// Single value string
if (typeof extended === 'string') {
return new Template(extended);
}
// Single value template
if (Template.isTemplate(extended)) {
return extended;
}
// By error code { 'number.min': <string | template> }
const target = Clone(base);
for (let code in extended) {
const message = extended[code];
if (code === 'root' ||
Template.isTemplate(message)) {
target[code] = message;
continue;
}
if (typeof message === 'string') {
target[code] = new Template(message);
continue;
}
// By language { english: { 'number.min': <string | template> } }
Assert(typeof message === 'object' && !Array.isArray(message), 'Invalid message for', code);
const language = code;
target[language] = target[language] || {};
for (code in message) {
const localized = message[code];
if (code === 'root' ||
Template.isTemplate(localized)) {
target[language][code] = localized;
continue;
}
Assert(typeof localized === 'string', 'Invalid message for', code, 'in', language);
target[language][code] = new Template(localized);
}
}
return target;
};

267
node_modules/joi/lib/modify.js generated vendored Normal file
View File

@ -0,0 +1,267 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Common = require('./common');
const Ref = require('./ref');
const internals = {};
exports.Ids = internals.Ids = class {
constructor() {
this._byId = new Map();
this._byKey = new Map();
this._schemaChain = false;
}
clone() {
const clone = new internals.Ids();
clone._byId = new Map(this._byId);
clone._byKey = new Map(this._byKey);
clone._schemaChain = this._schemaChain;
return clone;
}
concat(source) {
if (source._schemaChain) {
this._schemaChain = true;
}
for (const [id, value] of source._byId.entries()) {
Assert(!this._byKey.has(id), 'Schema id conflicts with existing key:', id);
this._byId.set(id, value);
}
for (const [key, value] of source._byKey.entries()) {
Assert(!this._byId.has(key), 'Schema key conflicts with existing id:', key);
this._byKey.set(key, value);
}
}
fork(path, adjuster, root) {
const chain = this._collect(path);
chain.push({ schema: root });
const tail = chain.shift();
let adjusted = { id: tail.id, schema: adjuster(tail.schema) };
Assert(Common.isSchema(adjusted.schema), 'adjuster function failed to return a joi schema type');
for (const node of chain) {
adjusted = { id: node.id, schema: internals.fork(node.schema, adjusted.id, adjusted.schema) };
}
return adjusted.schema;
}
labels(path, behind = []) {
const current = path[0];
const node = this._get(current);
if (!node) {
return [...behind, ...path].join('.');
}
const forward = path.slice(1);
behind = [...behind, node.schema._flags.label || current];
if (!forward.length) {
return behind.join('.');
}
return node.schema._ids.labels(forward, behind);
}
reach(path, behind = []) {
const current = path[0];
const node = this._get(current);
Assert(node, 'Schema does not contain path', [...behind, ...path].join('.'));
const forward = path.slice(1);
if (!forward.length) {
return node.schema;
}
return node.schema._ids.reach(forward, [...behind, current]);
}
register(schema, { key } = {}) {
if (!schema ||
!Common.isSchema(schema)) {
return;
}
if (schema.$_property('schemaChain') ||
schema._ids._schemaChain) {
this._schemaChain = true;
}
const id = schema._flags.id;
if (id) {
const existing = this._byId.get(id);
Assert(!existing || existing.schema === schema, 'Cannot add different schemas with the same id:', id);
Assert(!this._byKey.has(id), 'Schema id conflicts with existing key:', id);
this._byId.set(id, { schema, id });
}
if (key) {
Assert(!this._byKey.has(key), 'Schema already contains key:', key);
Assert(!this._byId.has(key), 'Schema key conflicts with existing id:', key);
this._byKey.set(key, { schema, id: key });
}
}
reset() {
this._byId = new Map();
this._byKey = new Map();
this._schemaChain = false;
}
_collect(path, behind = [], nodes = []) {
const current = path[0];
const node = this._get(current);
Assert(node, 'Schema does not contain path', [...behind, ...path].join('.'));
nodes = [node, ...nodes];
const forward = path.slice(1);
if (!forward.length) {
return nodes;
}
return node.schema._ids._collect(forward, [...behind, current], nodes);
}
_get(id) {
return this._byId.get(id) || this._byKey.get(id);
}
};
internals.fork = function (schema, id, replacement) {
const each = (item, { key }) => {
if (id === (item._flags.id || key)) {
return replacement;
}
};
const obj = exports.schema(schema, { each, ref: false });
return obj ? obj.$_mutateRebuild() : schema;
};
exports.schema = function (schema, options) {
let obj;
for (const name in schema._flags) {
if (name[0] === '_') {
continue;
}
const result = internals.scan(schema._flags[name], { source: 'flags', name }, options);
if (result !== undefined) {
obj = obj || schema.clone();
obj._flags[name] = result;
}
}
for (let i = 0; i < schema._rules.length; ++i) {
const rule = schema._rules[i];
const result = internals.scan(rule.args, { source: 'rules', name: rule.name }, options);
if (result !== undefined) {
obj = obj || schema.clone();
const clone = Object.assign({}, rule);
clone.args = result;
obj._rules[i] = clone;
const existingUnique = obj._singleRules.get(rule.name);
if (existingUnique === rule) {
obj._singleRules.set(rule.name, clone);
}
}
}
for (const name in schema.$_terms) {
if (name[0] === '_') {
continue;
}
const result = internals.scan(schema.$_terms[name], { source: 'terms', name }, options);
if (result !== undefined) {
obj = obj || schema.clone();
obj.$_terms[name] = result;
}
}
return obj;
};
internals.scan = function (item, source, options, _path, _key) {
const path = _path || [];
if (item === null ||
typeof item !== 'object') {
return;
}
let clone;
if (Array.isArray(item)) {
for (let i = 0; i < item.length; ++i) {
const key = source.source === 'terms' && source.name === 'keys' && item[i].key;
const result = internals.scan(item[i], source, options, [i, ...path], key);
if (result !== undefined) {
clone = clone || item.slice();
clone[i] = result;
}
}
return clone;
}
if (options.schema !== false && Common.isSchema(item) ||
options.ref !== false && Ref.isRef(item)) {
const result = options.each(item, { ...source, path, key: _key });
if (result === item) {
return;
}
return result;
}
for (const key in item) {
if (key[0] === '_') {
continue;
}
const result = internals.scan(item[key], source, options, [key, ...path], _key);
if (result !== undefined) {
clone = clone || Object.assign({}, item);
clone[key] = result;
}
}
return clone;
};

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

@ -0,0 +1,414 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Clone = require('@hapi/hoek/lib/clone');
const Reach = require('@hapi/hoek/lib/reach');
const Common = require('./common');
let Template;
const internals = {
symbol: Symbol('ref'), // Used to internally identify references (shared with other joi versions)
defaults: {
adjust: null,
in: false,
iterables: null,
map: null,
separator: '.',
type: 'value'
}
};
exports.create = function (key, options = {}) {
Assert(typeof key === 'string', 'Invalid reference key:', key);
Common.assertOptions(options, ['adjust', 'ancestor', 'in', 'iterables', 'map', 'prefix', 'render', 'separator']);
Assert(!options.prefix || typeof options.prefix === 'object', 'options.prefix must be of type object');
const ref = Object.assign({}, internals.defaults, options);
delete ref.prefix;
const separator = ref.separator;
const context = internals.context(key, separator, options.prefix);
ref.type = context.type;
key = context.key;
if (ref.type === 'value') {
if (context.root) {
Assert(!separator || key[0] !== separator, 'Cannot specify relative path with root prefix');
ref.ancestor = 'root';
if (!key) {
key = null;
}
}
if (separator &&
separator === key) {
key = null;
ref.ancestor = 0;
}
else {
if (ref.ancestor !== undefined) {
Assert(!separator || !key || key[0] !== separator, 'Cannot combine prefix with ancestor option');
}
else {
const [ancestor, slice] = internals.ancestor(key, separator);
if (slice) {
key = key.slice(slice);
if (key === '') {
key = null;
}
}
ref.ancestor = ancestor;
}
}
}
ref.path = separator ? (key === null ? [] : key.split(separator)) : [key];
return new internals.Ref(ref);
};
exports.in = function (key, options = {}) {
return exports.create(key, { ...options, in: true });
};
exports.isRef = function (ref) {
return ref ? !!ref[Common.symbols.ref] : false;
};
internals.Ref = class {
constructor(options) {
Assert(typeof options === 'object', 'Invalid reference construction');
Common.assertOptions(options, [
'adjust', 'ancestor', 'in', 'iterables', 'map', 'path', 'render', 'separator', 'type', // Copied
'depth', 'key', 'root', 'display' // Overridden
]);
Assert([false, undefined].includes(options.separator) || typeof options.separator === 'string' && options.separator.length === 1, 'Invalid separator');
Assert(!options.adjust || typeof options.adjust === 'function', 'options.adjust must be a function');
Assert(!options.map || Array.isArray(options.map), 'options.map must be an array');
Assert(!options.map || !options.adjust, 'Cannot set both map and adjust options');
Object.assign(this, internals.defaults, options);
Assert(this.type === 'value' || this.ancestor === undefined, 'Non-value references cannot reference ancestors');
if (Array.isArray(this.map)) {
this.map = new Map(this.map);
}
this.depth = this.path.length;
this.key = this.path.length ? this.path.join(this.separator) : null;
this.root = this.path[0];
this.updateDisplay();
}
resolve(value, state, prefs, local, options = {}) {
Assert(!this.in || options.in, 'Invalid in() reference usage');
if (this.type === 'global') {
return this._resolve(prefs.context, state, options);
}
if (this.type === 'local') {
return this._resolve(local, state, options);
}
if (!this.ancestor) {
return this._resolve(value, state, options);
}
if (this.ancestor === 'root') {
return this._resolve(state.ancestors[state.ancestors.length - 1], state, options);
}
Assert(this.ancestor <= state.ancestors.length, 'Invalid reference exceeds the schema root:', this.display);
return this._resolve(state.ancestors[this.ancestor - 1], state, options);
}
_resolve(target, state, options) {
let resolved;
if (this.type === 'value' &&
state.mainstay.shadow &&
options.shadow !== false) {
resolved = state.mainstay.shadow.get(this.absolute(state));
}
if (resolved === undefined) {
resolved = Reach(target, this.path, { iterables: this.iterables, functions: true });
}
if (this.adjust) {
resolved = this.adjust(resolved);
}
if (this.map) {
const mapped = this.map.get(resolved);
if (mapped !== undefined) {
resolved = mapped;
}
}
if (state.mainstay) {
state.mainstay.tracer.resolve(state, this, resolved);
}
return resolved;
}
toString() {
return this.display;
}
absolute(state) {
return [...state.path.slice(0, -this.ancestor), ...this.path];
}
clone() {
return new internals.Ref(this);
}
describe() {
const ref = { path: this.path };
if (this.type !== 'value') {
ref.type = this.type;
}
if (this.separator !== '.') {
ref.separator = this.separator;
}
if (this.type === 'value' &&
this.ancestor !== 1) {
ref.ancestor = this.ancestor;
}
if (this.map) {
ref.map = [...this.map];
}
for (const key of ['adjust', 'iterables', 'render']) {
if (this[key] !== null &&
this[key] !== undefined) {
ref[key] = this[key];
}
}
if (this.in !== false) {
ref.in = true;
}
return { ref };
}
updateDisplay() {
const key = this.key !== null ? this.key : '';
if (this.type !== 'value') {
this.display = `ref:${this.type}:${key}`;
return;
}
if (!this.separator) {
this.display = `ref:${key}`;
return;
}
if (!this.ancestor) {
this.display = `ref:${this.separator}${key}`;
return;
}
if (this.ancestor === 'root') {
this.display = `ref:root:${key}`;
return;
}
if (this.ancestor === 1) {
this.display = `ref:${key || '..'}`;
return;
}
const lead = new Array(this.ancestor + 1).fill(this.separator).join('');
this.display = `ref:${lead}${key || ''}`;
}
};
internals.Ref.prototype[Common.symbols.ref] = true;
exports.build = function (desc) {
desc = Object.assign({}, internals.defaults, desc);
if (desc.type === 'value' &&
desc.ancestor === undefined) {
desc.ancestor = 1;
}
return new internals.Ref(desc);
};
internals.context = function (key, separator, prefix = {}) {
key = key.trim();
if (prefix) {
const globalp = prefix.global === undefined ? '$' : prefix.global;
if (globalp !== separator &&
key.startsWith(globalp)) {
return { key: key.slice(globalp.length), type: 'global' };
}
const local = prefix.local === undefined ? '#' : prefix.local;
if (local !== separator &&
key.startsWith(local)) {
return { key: key.slice(local.length), type: 'local' };
}
const root = prefix.root === undefined ? '/' : prefix.root;
if (root !== separator &&
key.startsWith(root)) {
return { key: key.slice(root.length), type: 'value', root: true };
}
}
return { key, type: 'value' };
};
internals.ancestor = function (key, separator) {
if (!separator) {
return [1, 0]; // 'a_b' -> 1 (parent)
}
if (key[0] !== separator) { // 'a.b' -> 1 (parent)
return [1, 0];
}
if (key[1] !== separator) { // '.a.b' -> 0 (self)
return [0, 1];
}
let i = 2;
while (key[i] === separator) {
++i;
}
return [i - 1, i]; // '...a.b.' -> 2 (grandparent)
};
exports.toSibling = 0;
exports.toParent = 1;
exports.Manager = class {
constructor() {
this.refs = []; // 0: [self refs], 1: [parent refs], 2: [grandparent refs], ...
}
register(source, target) {
if (!source) {
return;
}
target = target === undefined ? exports.toParent : target;
// Array
if (Array.isArray(source)) {
for (const ref of source) {
this.register(ref, target);
}
return;
}
// Schema
if (Common.isSchema(source)) {
for (const item of source._refs.refs) {
if (item.ancestor - target >= 0) {
this.refs.push({ ancestor: item.ancestor - target, root: item.root });
}
}
return;
}
// Reference
if (exports.isRef(source) &&
source.type === 'value' &&
source.ancestor - target >= 0) {
this.refs.push({ ancestor: source.ancestor - target, root: source.root });
}
// Template
Template = Template || require('./template');
if (Template.isTemplate(source)) {
this.register(source.refs(), target);
}
}
get length() {
return this.refs.length;
}
clone() {
const copy = new exports.Manager();
copy.refs = Clone(this.refs);
return copy;
}
reset() {
this.refs = [];
}
roots() {
return this.refs.filter((ref) => !ref.ancestor).map((ref) => ref.root);
}
};

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

@ -0,0 +1,302 @@
'use strict';
const Joi = require('./index');
const internals = {};
// Preferences
internals.wrap = Joi.string()
.min(1)
.max(2)
.allow(false);
exports.preferences = Joi.object({
allowUnknown: Joi.boolean(),
abortEarly: Joi.boolean(),
artifacts: Joi.boolean(),
cache: Joi.boolean(),
context: Joi.object(),
convert: Joi.boolean(),
dateFormat: Joi.valid('date', 'iso', 'string', 'time', 'utc'),
debug: Joi.boolean(),
errors: {
escapeHtml: Joi.boolean(),
label: Joi.valid('path', 'key', false),
language: [
Joi.string(),
Joi.object().ref()
],
render: Joi.boolean(),
stack: Joi.boolean(),
wrap: {
label: internals.wrap,
array: internals.wrap,
string: internals.wrap
}
},
externals: Joi.boolean(),
messages: Joi.object(),
noDefaults: Joi.boolean(),
nonEnumerables: Joi.boolean(),
presence: Joi.valid('required', 'optional', 'forbidden'),
skipFunctions: Joi.boolean(),
stripUnknown: Joi.object({
arrays: Joi.boolean(),
objects: Joi.boolean()
})
.or('arrays', 'objects')
.allow(true, false),
warnings: Joi.boolean()
})
.strict();
// Extensions
internals.nameRx = /^[a-zA-Z0-9]\w*$/;
internals.rule = Joi.object({
alias: Joi.array().items(Joi.string().pattern(internals.nameRx)).single(),
args: Joi.array().items(
Joi.string(),
Joi.object({
name: Joi.string().pattern(internals.nameRx).required(),
ref: Joi.boolean(),
assert: Joi.alternatives([
Joi.function(),
Joi.object().schema()
])
.conditional('ref', { is: true, then: Joi.required() }),
normalize: Joi.function(),
message: Joi.string().when('assert', { is: Joi.function(), then: Joi.required() })
})
),
convert: Joi.boolean(),
manifest: Joi.boolean(),
method: Joi.function().allow(false),
multi: Joi.boolean(),
validate: Joi.function()
});
exports.extension = Joi.object({
type: Joi.alternatives([
Joi.string(),
Joi.object().regex()
])
.required(),
args: Joi.function(),
cast: Joi.object().pattern(internals.nameRx, Joi.object({
from: Joi.function().maxArity(1).required(),
to: Joi.function().minArity(1).maxArity(2).required()
})),
base: Joi.object().schema()
.when('type', { is: Joi.object().regex(), then: Joi.forbidden() }),
coerce: [
Joi.function().maxArity(3),
Joi.object({ method: Joi.function().maxArity(3).required(), from: Joi.array().items(Joi.string()).single() })
],
flags: Joi.object().pattern(internals.nameRx, Joi.object({
setter: Joi.string(),
default: Joi.any()
})),
manifest: {
build: Joi.function().arity(2)
},
messages: [Joi.object(), Joi.string()],
modifiers: Joi.object().pattern(internals.nameRx, Joi.function().minArity(1).maxArity(2)),
overrides: Joi.object().pattern(internals.nameRx, Joi.function()),
prepare: Joi.function().maxArity(3),
rebuild: Joi.function().arity(1),
rules: Joi.object().pattern(internals.nameRx, internals.rule),
terms: Joi.object().pattern(internals.nameRx, Joi.object({
init: Joi.array().allow(null).required(),
manifest: Joi.object().pattern(/.+/, [
Joi.valid('schema', 'single'),
Joi.object({
mapped: Joi.object({
from: Joi.string().required(),
to: Joi.string().required()
})
.required()
})
])
})),
validate: Joi.function().maxArity(3)
})
.strict();
exports.extensions = Joi.array().items(Joi.object(), Joi.function().arity(1)).strict();
// Manifest
internals.desc = {
buffer: Joi.object({
buffer: Joi.string()
}),
func: Joi.object({
function: Joi.function().required(),
options: {
literal: true
}
}),
override: Joi.object({
override: true
}),
ref: Joi.object({
ref: Joi.object({
type: Joi.valid('value', 'global', 'local'),
path: Joi.array().required(),
separator: Joi.string().length(1).allow(false),
ancestor: Joi.number().min(0).integer().allow('root'),
map: Joi.array().items(Joi.array().length(2)).min(1),
adjust: Joi.function(),
iterables: Joi.boolean(),
in: Joi.boolean(),
render: Joi.boolean()
})
.required()
}),
regex: Joi.object({
regex: Joi.string().min(3)
}),
special: Joi.object({
special: Joi.valid('deep').required()
}),
template: Joi.object({
template: Joi.string().required(),
options: Joi.object()
}),
value: Joi.object({
value: Joi.alternatives([Joi.object(), Joi.array()]).required()
})
};
internals.desc.entity = Joi.alternatives([
Joi.array().items(Joi.link('...')),
Joi.boolean(),
Joi.function(),
Joi.number(),
Joi.string(),
internals.desc.buffer,
internals.desc.func,
internals.desc.ref,
internals.desc.regex,
internals.desc.special,
internals.desc.template,
internals.desc.value,
Joi.link('/')
]);
internals.desc.values = Joi.array()
.items(
null,
Joi.boolean(),
Joi.function(),
Joi.number().allow(Infinity, -Infinity),
Joi.string().allow(''),
Joi.symbol(),
internals.desc.buffer,
internals.desc.func,
internals.desc.override,
internals.desc.ref,
internals.desc.regex,
internals.desc.template,
internals.desc.value
);
internals.desc.messages = Joi.object()
.pattern(/.+/, [
Joi.string(),
internals.desc.template,
Joi.object().pattern(/.+/, [Joi.string(), internals.desc.template])
]);
exports.description = Joi.object({
type: Joi.string().required(),
flags: Joi.object({
cast: Joi.string(),
default: Joi.any(),
description: Joi.string(),
empty: Joi.link('/'),
failover: internals.desc.entity,
id: Joi.string(),
label: Joi.string(),
only: true,
presence: ['optional', 'required', 'forbidden'],
result: ['raw', 'strip'],
strip: Joi.boolean(),
unit: Joi.string()
})
.unknown(),
preferences: {
allowUnknown: Joi.boolean(),
abortEarly: Joi.boolean(),
artifacts: Joi.boolean(),
cache: Joi.boolean(),
convert: Joi.boolean(),
dateFormat: ['date', 'iso', 'string', 'time', 'utc'],
errors: {
escapeHtml: Joi.boolean(),
label: ['path', 'key'],
language: [
Joi.string(),
internals.desc.ref
],
wrap: {
label: internals.wrap,
array: internals.wrap
}
},
externals: Joi.boolean(),
messages: internals.desc.messages,
noDefaults: Joi.boolean(),
nonEnumerables: Joi.boolean(),
presence: ['required', 'optional', 'forbidden'],
skipFunctions: Joi.boolean(),
stripUnknown: Joi.object({
arrays: Joi.boolean(),
objects: Joi.boolean()
})
.or('arrays', 'objects')
.allow(true, false),
warnings: Joi.boolean()
},
allow: internals.desc.values,
invalid: internals.desc.values,
rules: Joi.array().min(1).items({
name: Joi.string().required(),
args: Joi.object().min(1),
keep: Joi.boolean(),
message: [
Joi.string(),
internals.desc.messages
],
warn: Joi.boolean()
}),
// Terms
keys: Joi.object().pattern(/.*/, Joi.link('/')),
link: internals.desc.ref
})
.pattern(/^[a-z]\w*$/, Joi.any());

166
node_modules/joi/lib/state.js generated vendored Normal file
View File

@ -0,0 +1,166 @@
'use strict';
const Clone = require('@hapi/hoek/lib/clone');
const Reach = require('@hapi/hoek/lib/reach');
const Common = require('./common');
const internals = {
value: Symbol('value')
};
module.exports = internals.State = class {
constructor(path, ancestors, state) {
this.path = path;
this.ancestors = ancestors; // [parent, ..., root]
this.mainstay = state.mainstay;
this.schemas = state.schemas; // [current, ..., root]
this.debug = null;
}
localize(path, ancestors = null, schema = null) {
const state = new internals.State(path, ancestors, this);
if (schema &&
state.schemas) {
state.schemas = [internals.schemas(schema), ...state.schemas];
}
return state;
}
nest(schema, debug) {
const state = new internals.State(this.path, this.ancestors, this);
state.schemas = state.schemas && [internals.schemas(schema), ...state.schemas];
state.debug = debug;
return state;
}
shadow(value, reason) {
this.mainstay.shadow = this.mainstay.shadow || new internals.Shadow();
this.mainstay.shadow.set(this.path, value, reason);
}
snapshot() {
if (this.mainstay.shadow) {
this._snapshot = Clone(this.mainstay.shadow.node(this.path));
}
this.mainstay.snapshot();
}
restore() {
if (this.mainstay.shadow) {
this.mainstay.shadow.override(this.path, this._snapshot);
this._snapshot = undefined;
}
this.mainstay.restore();
}
commit() {
if (this.mainstay.shadow) {
this.mainstay.shadow.override(this.path, this._snapshot);
this._snapshot = undefined;
}
this.mainstay.commit();
}
};
internals.schemas = function (schema) {
if (Common.isSchema(schema)) {
return { schema };
}
return schema;
};
internals.Shadow = class {
constructor() {
this._values = null;
}
set(path, value, reason) {
if (!path.length) { // No need to store root value
return;
}
if (reason === 'strip' &&
typeof path[path.length - 1] === 'number') { // Cannot store stripped array values (due to shift)
return;
}
this._values = this._values || new Map();
let node = this._values;
for (let i = 0; i < path.length; ++i) {
const segment = path[i];
let next = node.get(segment);
if (!next) {
next = new Map();
node.set(segment, next);
}
node = next;
}
node[internals.value] = value;
}
get(path) {
const node = this.node(path);
if (node) {
return node[internals.value];
}
}
node(path) {
if (!this._values) {
return;
}
return Reach(this._values, path, { iterables: true });
}
override(path, node) {
if (!this._values) {
return;
}
const parents = path.slice(0, -1);
const own = path[path.length - 1];
const parent = Reach(this._values, parents, { iterables: true });
if (node) {
parent.set(own, node);
return;
}
if (parent) {
parent.delete(own);
}
}
};

441
node_modules/joi/lib/template.js generated vendored Normal file
View File

@ -0,0 +1,441 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Clone = require('@hapi/hoek/lib/clone');
const EscapeHtml = require('@hapi/hoek/lib/escapeHtml');
const Formula = require('@sideway/formula');
const Common = require('./common');
const Errors = require('./errors');
const Ref = require('./ref');
const internals = {
symbol: Symbol('template'),
opens: new Array(1000).join('\u0000'),
closes: new Array(1000).join('\u0001'),
dateFormat: {
date: Date.prototype.toDateString,
iso: Date.prototype.toISOString,
string: Date.prototype.toString,
time: Date.prototype.toTimeString,
utc: Date.prototype.toUTCString
}
};
module.exports = exports = internals.Template = class {
constructor(source, options) {
Assert(typeof source === 'string', 'Template source must be a string');
Assert(!source.includes('\u0000') && !source.includes('\u0001'), 'Template source cannot contain reserved control characters');
this.source = source;
this.rendered = source;
this._template = null;
this._settings = Clone(options);
this._parse();
}
_parse() {
// 'text {raw} {{ref}} \\{{ignore}} {{ignore\\}} {{ignore {{ignore}'
if (!this.source.includes('{')) {
return;
}
// Encode escaped \\{{{{{
const encoded = internals.encode(this.source);
// Split on first { in each set
const parts = internals.split(encoded);
// Process parts
let refs = false;
const processed = [];
const head = parts.shift();
if (head) {
processed.push(head);
}
for (const part of parts) {
const raw = part[0] !== '{';
const ender = raw ? '}' : '}}';
const end = part.indexOf(ender);
if (end === -1 || // Ignore non-matching closing
part[1] === '{') { // Ignore more than two {
processed.push(`{${internals.decode(part)}`);
continue;
}
let variable = part.slice(raw ? 0 : 1, end);
const wrapped = variable[0] === ':';
if (wrapped) {
variable = variable.slice(1);
}
const dynamic = this._ref(internals.decode(variable), { raw, wrapped });
processed.push(dynamic);
if (typeof dynamic !== 'string') {
refs = true;
}
const rest = part.slice(end + ender.length);
if (rest) {
processed.push(internals.decode(rest));
}
}
if (!refs) {
this.rendered = processed.join('');
return;
}
this._template = processed;
}
static date(date, prefs) {
return internals.dateFormat[prefs.dateFormat].call(date);
}
describe(options = {}) {
if (!this._settings &&
options.compact) {
return this.source;
}
const desc = { template: this.source };
if (this._settings) {
desc.options = this._settings;
}
return desc;
}
static build(desc) {
return new internals.Template(desc.template, desc.options);
}
isDynamic() {
return !!this._template;
}
static isTemplate(template) {
return template ? !!template[Common.symbols.template] : false;
}
refs() {
if (!this._template) {
return;
}
const refs = [];
for (const part of this._template) {
if (typeof part !== 'string') {
refs.push(...part.refs);
}
}
return refs;
}
resolve(value, state, prefs, local) {
if (this._template &&
this._template.length === 1) {
return this._part(this._template[0], /* context -> [*/ value, state, prefs, local, {} /*] */);
}
return this.render(value, state, prefs, local);
}
_part(part, ...args) {
if (part.ref) {
return part.ref.resolve(...args);
}
return part.formula.evaluate(args);
}
render(value, state, prefs, local, options = {}) {
if (!this.isDynamic()) {
return this.rendered;
}
const parts = [];
for (const part of this._template) {
if (typeof part === 'string') {
parts.push(part);
}
else {
const rendered = this._part(part, /* context -> [*/ value, state, prefs, local, options /*] */);
const string = internals.stringify(rendered, value, state, prefs, local, options);
if (string !== undefined) {
const result = part.raw || (options.errors && options.errors.escapeHtml) === false ? string : EscapeHtml(string);
parts.push(internals.wrap(result, part.wrapped && prefs.errors.wrap.label));
}
}
}
return parts.join('');
}
_ref(content, { raw, wrapped }) {
const refs = [];
const reference = (variable) => {
const ref = Ref.create(variable, this._settings);
refs.push(ref);
return (context) => ref.resolve(...context);
};
try {
var formula = new Formula.Parser(content, { reference, functions: internals.functions, constants: internals.constants });
}
catch (err) {
err.message = `Invalid template variable "${content}" fails due to: ${err.message}`;
throw err;
}
if (formula.single) {
if (formula.single.type === 'reference') {
const ref = refs[0];
return { ref, raw, refs, wrapped: wrapped || ref.type === 'local' && ref.key === 'label' };
}
return internals.stringify(formula.single.value);
}
return { formula, raw, refs };
}
toString() {
return this.source;
}
};
internals.Template.prototype[Common.symbols.template] = true;
internals.Template.prototype.isImmutable = true; // Prevents Hoek from deep cloning schema objects
internals.encode = function (string) {
return string
.replace(/\\(\{+)/g, ($0, $1) => {
return internals.opens.slice(0, $1.length);
})
.replace(/\\(\}+)/g, ($0, $1) => {
return internals.closes.slice(0, $1.length);
});
};
internals.decode = function (string) {
return string
.replace(/\u0000/g, '{')
.replace(/\u0001/g, '}');
};
internals.split = function (string) {
const parts = [];
let current = '';
for (let i = 0; i < string.length; ++i) {
const char = string[i];
if (char === '{') {
let next = '';
while (i + 1 < string.length &&
string[i + 1] === '{') {
next += '{';
++i;
}
parts.push(current);
current = next;
}
else {
current += char;
}
}
parts.push(current);
return parts;
};
internals.wrap = function (value, ends) {
if (!ends) {
return value;
}
if (ends.length === 1) {
return `${ends}${value}${ends}`;
}
return `${ends[0]}${value}${ends[1]}`;
};
internals.stringify = function (value, original, state, prefs, local, options = {}) {
const type = typeof value;
const wrap = prefs && prefs.errors && prefs.errors.wrap || {};
let skipWrap = false;
if (Ref.isRef(value) &&
value.render) {
skipWrap = value.in;
value = value.resolve(original, state, prefs, local, { in: value.in, ...options });
}
if (value === null) {
return 'null';
}
if (type === 'string') {
return internals.wrap(value, options.arrayItems && wrap.string);
}
if (type === 'number' ||
type === 'function' ||
type === 'symbol') {
return value.toString();
}
if (type !== 'object') {
return JSON.stringify(value);
}
if (value instanceof Date) {
return internals.Template.date(value, prefs);
}
if (value instanceof Map) {
const pairs = [];
for (const [key, sym] of value.entries()) {
pairs.push(`${key.toString()} -> ${sym.toString()}`);
}
value = pairs;
}
if (!Array.isArray(value)) {
return value.toString();
}
const values = [];
for (const item of value) {
values.push(internals.stringify(item, original, state, prefs, local, { arrayItems: true, ...options }));
}
return internals.wrap(values.join(', '), !skipWrap && wrap.array);
};
internals.constants = {
true: true,
false: false,
null: null,
second: 1000,
minute: 60 * 1000,
hour: 60 * 60 * 1000,
day: 24 * 60 * 60 * 1000
};
internals.functions = {
if(condition, then, otherwise) {
return condition ? then : otherwise;
},
length(item) {
if (typeof item === 'string') {
return item.length;
}
if (!item || typeof item !== 'object') {
return null;
}
if (Array.isArray(item)) {
return item.length;
}
return Object.keys(item).length;
},
msg(code) {
const [value, state, prefs, local, options] = this;
const messages = options.messages;
if (!messages) {
return '';
}
const template = Errors.template(value, messages[0], code, state, prefs) || Errors.template(value, messages[1], code, state, prefs);
if (!template) {
return '';
}
return template.render(value, state, prefs, local, options);
},
number(value) {
if (typeof value === 'number') {
return value;
}
if (typeof value === 'string') {
return parseFloat(value);
}
if (typeof value === 'boolean') {
return value ? 1 : 0;
}
if (value instanceof Date) {
return value.getTime();
}
return null;
}
};

346
node_modules/joi/lib/trace.js generated vendored Normal file
View File

@ -0,0 +1,346 @@
'use strict';
const DeepEqual = require('@hapi/hoek/lib/deepEqual');
const Pinpoint = require('@sideway/pinpoint');
const Errors = require('./errors');
const internals = {
codes: {
error: 1,
pass: 2,
full: 3
},
labels: {
0: 'never used',
1: 'always error',
2: 'always pass'
}
};
exports.setup = function (root) {
const trace = function () {
root._tracer = root._tracer || new internals.Tracer();
return root._tracer;
};
root.trace = trace;
root[Symbol.for('@hapi/lab/coverage/initialize')] = trace;
root.untrace = () => {
root._tracer = null;
};
};
exports.location = function (schema) {
return schema.$_setFlag('_tracerLocation', Pinpoint.location(2)); // base.tracer(), caller
};
internals.Tracer = class {
constructor() {
this.name = 'Joi';
this._schemas = new Map();
}
_register(schema) {
const existing = this._schemas.get(schema);
if (existing) {
return existing.store;
}
const store = new internals.Store(schema);
const { filename, line } = schema._flags._tracerLocation || Pinpoint.location(5); // internals.tracer(), internals.entry(), exports.entry(), validate(), caller
this._schemas.set(schema, { filename, line, store });
return store;
}
_combine(merged, sources) {
for (const { store } of this._schemas.values()) {
store._combine(merged, sources);
}
}
report(file) {
const coverage = [];
// Process each registered schema
for (const { filename, line, store } of this._schemas.values()) {
if (file &&
file !== filename) {
continue;
}
// Process sub schemas of the registered root
const missing = [];
const skipped = [];
for (const [schema, log] of store._sources.entries()) {
// Check if sub schema parent skipped
if (internals.sub(log.paths, skipped)) {
continue;
}
// Check if sub schema reached
if (!log.entry) {
missing.push({
status: 'never reached',
paths: [...log.paths]
});
skipped.push(...log.paths);
continue;
}
// Check values
for (const type of ['valid', 'invalid']) {
const set = schema[`_${type}s`];
if (!set) {
continue;
}
const values = new Set(set._values);
const refs = new Set(set._refs);
for (const { value, ref } of log[type]) {
values.delete(value);
refs.delete(ref);
}
if (values.size ||
refs.size) {
missing.push({
status: [...values, ...[...refs].map((ref) => ref.display)],
rule: `${type}s`
});
}
}
// Check rules status
const rules = schema._rules.map((rule) => rule.name);
for (const type of ['default', 'failover']) {
if (schema._flags[type] !== undefined) {
rules.push(type);
}
}
for (const name of rules) {
const status = internals.labels[log.rule[name] || 0];
if (status) {
const report = { rule: name, status };
if (log.paths.size) {
report.paths = [...log.paths];
}
missing.push(report);
}
}
}
if (missing.length) {
coverage.push({
filename,
line,
missing,
severity: 'error',
message: `Schema missing tests for ${missing.map(internals.message).join(', ')}`
});
}
}
return coverage.length ? coverage : null;
}
};
internals.Store = class {
constructor(schema) {
this.active = true;
this._sources = new Map(); // schema -> { paths, entry, rule, valid, invalid }
this._combos = new Map(); // merged -> [sources]
this._scan(schema);
}
debug(state, source, name, result) {
state.mainstay.debug && state.mainstay.debug.push({ type: source, name, result, path: state.path });
}
entry(schema, state) {
internals.debug(state, { type: 'entry' });
this._record(schema, (log) => {
log.entry = true;
});
}
filter(schema, state, source, value) {
internals.debug(state, { type: source, ...value });
this._record(schema, (log) => {
log[source].add(value);
});
}
log(schema, state, source, name, result) {
internals.debug(state, { type: source, name, result: result === 'full' ? 'pass' : result });
this._record(schema, (log) => {
log[source][name] = log[source][name] || 0;
log[source][name] |= internals.codes[result];
});
}
resolve(state, ref, to) {
if (!state.mainstay.debug) {
return;
}
const log = { type: 'resolve', ref: ref.display, to, path: state.path };
state.mainstay.debug.push(log);
}
value(state, by, from, to, name) {
if (!state.mainstay.debug ||
DeepEqual(from, to)) {
return;
}
const log = { type: 'value', by, from, to, path: state.path };
if (name) {
log.name = name;
}
state.mainstay.debug.push(log);
}
_record(schema, each) {
const log = this._sources.get(schema);
if (log) {
each(log);
return;
}
const sources = this._combos.get(schema);
for (const source of sources) {
this._record(source, each);
}
}
_scan(schema, _path) {
const path = _path || [];
let log = this._sources.get(schema);
if (!log) {
log = {
paths: new Set(),
entry: false,
rule: {},
valid: new Set(),
invalid: new Set()
};
this._sources.set(schema, log);
}
if (path.length) {
log.paths.add(path);
}
const each = (sub, source) => {
const subId = internals.id(sub, source);
this._scan(sub, path.concat(subId));
};
schema.$_modify({ each, ref: false });
}
_combine(merged, sources) {
this._combos.set(merged, sources);
}
};
internals.message = function (item) {
const path = item.paths ? Errors.path(item.paths[0]) + (item.rule ? ':' : '') : '';
return `${path}${item.rule || ''} (${item.status})`;
};
internals.id = function (schema, { source, name, path, key }) {
if (schema._flags.id) {
return schema._flags.id;
}
if (key) {
return key;
}
name = `@${name}`;
if (source === 'terms') {
return [name, path[Math.min(path.length - 1, 1)]];
}
return name;
};
internals.sub = function (paths, skipped) {
for (const path of paths) {
for (const skip of skipped) {
if (DeepEqual(path.slice(0, skip.length), skip)) {
return true;
}
}
}
return false;
};
internals.debug = function (state, event) {
if (state.mainstay.debug) {
event.path = state.debug ? [...state.path, state.debug] : state.path;
state.mainstay.debug.push(event);
}
};

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

@ -0,0 +1,357 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Merge = require('@hapi/hoek/lib/merge');
const Any = require('./any');
const Common = require('../common');
const Compile = require('../compile');
const Errors = require('../errors');
const Ref = require('../ref');
const internals = {};
module.exports = Any.extend({
type: 'alternatives',
flags: {
match: { default: 'any' } // 'any', 'one', 'all'
},
terms: {
matches: { init: [], register: Ref.toSibling }
},
args(schema, ...schemas) {
if (schemas.length === 1) {
if (Array.isArray(schemas[0])) {
return schema.try(...schemas[0]);
}
}
return schema.try(...schemas);
},
validate(value, helpers) {
const { schema, error, state, prefs } = helpers;
// Match all or one
if (schema._flags.match) {
const matched = [];
const failed = [];
for (let i = 0; i < schema.$_terms.matches.length; ++i) {
const item = schema.$_terms.matches[i];
const localState = state.nest(item.schema, `match.${i}`);
localState.snapshot();
const result = item.schema.$_validate(value, localState, prefs);
if (!result.errors) {
matched.push(result.value);
localState.commit();
}
else {
failed.push(result.errors);
localState.restore();
}
}
if (matched.length === 0) {
const context = {
details: failed.map((f) => Errors.details(f, { override: false }))
};
return { errors: error('alternatives.any', context) };
}
// Match one
if (schema._flags.match === 'one') {
return matched.length === 1 ? { value: matched[0] } : { errors: error('alternatives.one') };
}
// Match all
if (matched.length !== schema.$_terms.matches.length) {
const context = {
details: failed.map((f) => Errors.details(f, { override: false }))
};
return { errors: error('alternatives.all', context) };
}
const isAnyObj = (alternative) => {
return alternative.$_terms.matches.some((v) => {
return v.schema.type === 'object' ||
(v.schema.type === 'alternatives' && isAnyObj(v.schema));
});
};
return isAnyObj(schema) ? { value: matched.reduce((acc, v) => Merge(acc, v, { mergeArrays: false })) } : { value: matched[matched.length - 1] };
}
// Match any
const errors = [];
for (let i = 0; i < schema.$_terms.matches.length; ++i) {
const item = schema.$_terms.matches[i];
// Try
if (item.schema) {
const localState = state.nest(item.schema, `match.${i}`);
localState.snapshot();
const result = item.schema.$_validate(value, localState, prefs);
if (!result.errors) {
localState.commit();
return result;
}
localState.restore();
errors.push({ schema: item.schema, reports: result.errors });
continue;
}
// Conditional
const input = item.ref ? item.ref.resolve(value, state, prefs) : value;
const tests = item.is ? [item] : item.switch;
for (let j = 0; j < tests.length; ++j) {
const test = tests[j];
const { is, then, otherwise } = test;
const id = `match.${i}${item.switch ? '.' + j : ''}`;
if (!is.$_match(input, state.nest(is, `${id}.is`), prefs)) {
if (otherwise) {
return otherwise.$_validate(value, state.nest(otherwise, `${id}.otherwise`), prefs);
}
}
else if (then) {
return then.$_validate(value, state.nest(then, `${id}.then`), prefs);
}
}
}
return internals.errors(errors, helpers);
},
rules: {
conditional: {
method(condition, options) {
Assert(!this._flags._endedSwitch, 'Unreachable condition');
Assert(!this._flags.match, 'Cannot combine match mode', this._flags.match, 'with conditional rule');
Assert(options.break === undefined, 'Cannot use break option with alternatives conditional');
const obj = this.clone();
const match = Compile.when(obj, condition, options);
const conditions = match.is ? [match] : match.switch;
for (const item of conditions) {
if (item.then &&
item.otherwise) {
obj.$_setFlag('_endedSwitch', true, { clone: false });
break;
}
}
obj.$_terms.matches.push(match);
return obj.$_mutateRebuild();
}
},
match: {
method(mode) {
Assert(['any', 'one', 'all'].includes(mode), 'Invalid alternatives match mode', mode);
if (mode !== 'any') {
for (const match of this.$_terms.matches) {
Assert(match.schema, 'Cannot combine match mode', mode, 'with conditional rules');
}
}
return this.$_setFlag('match', mode);
}
},
try: {
method(...schemas) {
Assert(schemas.length, 'Missing alternative schemas');
Common.verifyFlat(schemas, 'try');
Assert(!this._flags._endedSwitch, 'Unreachable condition');
const obj = this.clone();
for (const schema of schemas) {
obj.$_terms.matches.push({ schema: obj.$_compile(schema) });
}
return obj.$_mutateRebuild();
}
}
},
overrides: {
label(name) {
const obj = this.$_parent('label', name);
const each = (item, source) => (source.path[0] !== 'is' ? item.label(name) : undefined);
return obj.$_modify({ each, ref: false });
}
},
rebuild(schema) {
// Flag when an alternative type is an array
const each = (item) => {
if (Common.isSchema(item) &&
item.type === 'array') {
schema.$_setFlag('_arrayItems', true, { clone: false });
}
};
schema.$_modify({ each });
},
manifest: {
build(obj, desc) {
if (desc.matches) {
for (const match of desc.matches) {
const { schema, ref, is, not, then, otherwise } = match;
if (schema) {
obj = obj.try(schema);
}
else if (ref) {
obj = obj.conditional(ref, { is, then, not, otherwise, switch: match.switch });
}
else {
obj = obj.conditional(is, { then, otherwise });
}
}
}
return obj;
}
},
messages: {
'alternatives.all': '{{#label}} does not match all of the required types',
'alternatives.any': '{{#label}} does not match any of the allowed types',
'alternatives.match': '{{#label}} does not match any of the allowed types',
'alternatives.one': '{{#label}} matches more than one allowed type',
'alternatives.types': '{{#label}} must be one of {{#types}}'
}
});
// Helpers
internals.errors = function (failures, { error, state }) {
// Nothing matched due to type criteria rules
if (!failures.length) {
return { errors: error('alternatives.any') };
}
// Single error
if (failures.length === 1) {
return { errors: failures[0].reports };
}
// Analyze reasons
const valids = new Set();
const complex = [];
for (const { reports, schema } of failures) {
// Multiple errors (!abortEarly)
if (reports.length > 1) {
return internals.unmatched(failures, error);
}
// Custom error
const report = reports[0];
if (report instanceof Errors.Report === false) {
return internals.unmatched(failures, error);
}
// Internal object or array error
if (report.state.path.length !== state.path.length) {
complex.push({ type: schema.type, report });
continue;
}
// Valids
if (report.code === 'any.only') {
for (const valid of report.local.valids) {
valids.add(valid);
}
continue;
}
// Base type
const [type, code] = report.code.split('.');
if (code !== 'base') {
complex.push({ type: schema.type, report });
continue;
}
valids.add(type);
}
// All errors are base types or valids
if (!complex.length) {
return { errors: error('alternatives.types', { types: [...valids] }) };
}
// Single complex error
if (complex.length === 1) {
return { errors: complex[0].report };
}
return internals.unmatched(failures, error);
};
internals.unmatched = function (failures, error) {
const errors = [];
for (const failure of failures) {
errors.push(...failure.reports);
}
return { errors: error('alternatives.match', Errors.details(errors, { override: false })) };
};

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

@ -0,0 +1,174 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Base = require('../base');
const Common = require('../common');
const Messages = require('../messages');
const internals = {};
module.exports = Base.extend({
type: 'any',
flags: {
only: { default: false }
},
terms: {
alterations: { init: null },
examples: { init: null },
externals: { init: null },
metas: { init: [] },
notes: { init: [] },
shared: { init: null },
tags: { init: [] },
whens: { init: null }
},
rules: {
custom: {
method(method, description) {
Assert(typeof method === 'function', 'Method must be a function');
Assert(description === undefined || description && typeof description === 'string', 'Description must be a non-empty string');
return this.$_addRule({ name: 'custom', args: { method, description } });
},
validate(value, helpers, { method }) {
try {
return method(value, helpers);
}
catch (err) {
return helpers.error('any.custom', { error: err });
}
},
args: ['method', 'description'],
multi: true
},
messages: {
method(messages) {
return this.prefs({ messages });
}
},
shared: {
method(schema) {
Assert(Common.isSchema(schema) && schema._flags.id, 'Schema must be a schema with an id');
const obj = this.clone();
obj.$_terms.shared = obj.$_terms.shared || [];
obj.$_terms.shared.push(schema);
obj.$_mutateRegister(schema);
return obj;
}
},
warning: {
method(code, local) {
Assert(code && typeof code === 'string', 'Invalid warning code');
return this.$_addRule({ name: 'warning', args: { code, local }, warn: true });
},
validate(value, helpers, { code, local }) {
return helpers.error(code, local);
},
args: ['code', 'local'],
multi: true
}
},
modifiers: {
keep(rule, enabled = true) {
rule.keep = enabled;
},
message(rule, message) {
rule.message = Messages.compile(message);
},
warn(rule, enabled = true) {
rule.warn = enabled;
}
},
manifest: {
build(obj, desc) {
for (const key in desc) {
const values = desc[key];
if (['examples', 'externals', 'metas', 'notes', 'tags'].includes(key)) {
for (const value of values) {
obj = obj[key.slice(0, -1)](value);
}
continue;
}
if (key === 'alterations') {
const alter = {};
for (const { target, adjuster } of values) {
alter[target] = adjuster;
}
obj = obj.alter(alter);
continue;
}
if (key === 'whens') {
for (const value of values) {
const { ref, is, not, then, otherwise, concat } = value;
if (concat) {
obj = obj.concat(concat);
}
else if (ref) {
obj = obj.when(ref, { is, not, then, otherwise, switch: value.switch, break: value.break });
}
else {
obj = obj.when(is, { then, otherwise, break: value.break });
}
}
continue;
}
if (key === 'shared') {
for (const value of values) {
obj = obj.shared(value);
}
}
}
return obj;
}
},
messages: {
'any.custom': '{{#label}} failed custom validation because {{#error.message}}',
'any.default': '{{#label}} threw an error when running default method',
'any.failover': '{{#label}} threw an error when running failover method',
'any.invalid': '{{#label}} contains an invalid value',
'any.only': '{{#label}} must be {if(#valids.length == 1, "", "one of ")}{{#valids}}',
'any.ref': '{{#label}} {{#arg}} references {{:#ref}} which {{#reason}}',
'any.required': '{{#label}} is required',
'any.unknown': '{{#label}} is not allowed'
}
});

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

@ -0,0 +1,808 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const DeepEqual = require('@hapi/hoek/lib/deepEqual');
const Reach = require('@hapi/hoek/lib/reach');
const Any = require('./any');
const Common = require('../common');
const Compile = require('../compile');
const internals = {};
module.exports = Any.extend({
type: 'array',
flags: {
single: { default: false },
sparse: { default: false }
},
terms: {
items: { init: [], manifest: 'schema' },
ordered: { init: [], manifest: 'schema' },
_exclusions: { init: [] },
_inclusions: { init: [] },
_requireds: { init: [] }
},
coerce: {
from: 'object',
method(value, { schema, state, prefs }) {
if (!Array.isArray(value)) {
return;
}
const sort = schema.$_getRule('sort');
if (!sort) {
return;
}
return internals.sort(schema, value, sort.args.options, state, prefs);
}
},
validate(value, { schema, error }) {
if (!Array.isArray(value)) {
if (schema._flags.single) {
const single = [value];
single[Common.symbols.arraySingle] = true;
return { value: single };
}
return { errors: error('array.base') };
}
if (!schema.$_getRule('items') &&
!schema.$_terms.externals) {
return;
}
return { value: value.slice() }; // Clone the array so that we don't modify the original
},
rules: {
has: {
method(schema) {
schema = this.$_compile(schema, { appendPath: true });
const obj = this.$_addRule({ name: 'has', args: { schema } });
obj.$_mutateRegister(schema);
return obj;
},
validate(value, { state, prefs, error }, { schema: has }) {
const ancestors = [value, ...state.ancestors];
for (let i = 0; i < value.length; ++i) {
const localState = state.localize([...state.path, i], ancestors, has);
if (has.$_match(value[i], localState, prefs)) {
return value;
}
}
const patternLabel = has._flags.label;
if (patternLabel) {
return error('array.hasKnown', { patternLabel });
}
return error('array.hasUnknown', null);
},
multi: true
},
items: {
method(...schemas) {
Common.verifyFlat(schemas, 'items');
const obj = this.$_addRule('items');
for (let i = 0; i < schemas.length; ++i) {
const type = Common.tryWithPath(() => this.$_compile(schemas[i]), i, { append: true });
obj.$_terms.items.push(type);
}
return obj.$_mutateRebuild();
},
validate(value, { schema, error, state, prefs, errorsArray }) {
const requireds = schema.$_terms._requireds.slice();
const ordereds = schema.$_terms.ordered.slice();
const inclusions = [...schema.$_terms._inclusions, ...requireds];
const wasArray = !value[Common.symbols.arraySingle];
delete value[Common.symbols.arraySingle];
const errors = errorsArray();
let il = value.length;
for (let i = 0; i < il; ++i) {
const item = value[i];
let errored = false;
let isValid = false;
const key = wasArray ? i : new Number(i); // eslint-disable-line no-new-wrappers
const path = [...state.path, key];
// Sparse
if (!schema._flags.sparse &&
item === undefined) {
errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path)));
if (prefs.abortEarly) {
return errors;
}
ordereds.shift();
continue;
}
// Exclusions
const ancestors = [value, ...state.ancestors];
for (const exclusion of schema.$_terms._exclusions) {
if (!exclusion.$_match(item, state.localize(path, ancestors, exclusion), prefs, { presence: 'ignore' })) {
continue;
}
errors.push(error('array.excludes', { pos: i, value: item }, state.localize(path)));
if (prefs.abortEarly) {
return errors;
}
errored = true;
ordereds.shift();
break;
}
if (errored) {
continue;
}
// Ordered
if (schema.$_terms.ordered.length) {
if (ordereds.length) {
const ordered = ordereds.shift();
const res = ordered.$_validate(item, state.localize(path, ancestors, ordered), prefs);
if (!res.errors) {
if (ordered._flags.result === 'strip') {
internals.fastSplice(value, i);
--i;
--il;
}
else if (!schema._flags.sparse && res.value === undefined) {
errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path)));
if (prefs.abortEarly) {
return errors;
}
continue;
}
else {
value[i] = res.value;
}
}
else {
errors.push(...res.errors);
if (prefs.abortEarly) {
return errors;
}
}
continue;
}
else if (!schema.$_terms.items.length) {
errors.push(error('array.orderedLength', { pos: i, limit: schema.$_terms.ordered.length }));
if (prefs.abortEarly) {
return errors;
}
break; // No reason to continue since there are no other rules to validate other than array.orderedLength
}
}
// Requireds
const requiredChecks = [];
let jl = requireds.length;
for (let j = 0; j < jl; ++j) {
const localState = state.localize(path, ancestors, requireds[j]);
localState.snapshot();
const res = requireds[j].$_validate(item, localState, prefs);
requiredChecks[j] = res;
if (!res.errors) {
localState.commit();
value[i] = res.value;
isValid = true;
internals.fastSplice(requireds, j);
--j;
--jl;
if (!schema._flags.sparse &&
res.value === undefined) {
errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path)));
if (prefs.abortEarly) {
return errors;
}
}
break;
}
localState.restore();
}
if (isValid) {
continue;
}
// Inclusions
const stripUnknown = prefs.stripUnknown && !!prefs.stripUnknown.arrays || false;
jl = inclusions.length;
for (const inclusion of inclusions) {
// Avoid re-running requireds that already didn't match in the previous loop
let res;
const previousCheck = requireds.indexOf(inclusion);
if (previousCheck !== -1) {
res = requiredChecks[previousCheck];
}
else {
const localState = state.localize(path, ancestors, inclusion);
localState.snapshot();
res = inclusion.$_validate(item, localState, prefs);
if (!res.errors) {
localState.commit();
if (inclusion._flags.result === 'strip') {
internals.fastSplice(value, i);
--i;
--il;
}
else if (!schema._flags.sparse &&
res.value === undefined) {
errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path)));
errored = true;
}
else {
value[i] = res.value;
}
isValid = true;
break;
}
localState.restore();
}
// Return the actual error if only one inclusion defined
if (jl === 1) {
if (stripUnknown) {
internals.fastSplice(value, i);
--i;
--il;
isValid = true;
break;
}
errors.push(...res.errors);
if (prefs.abortEarly) {
return errors;
}
errored = true;
break;
}
}
if (errored) {
continue;
}
if ((schema.$_terms._inclusions.length || schema.$_terms._requireds.length) &&
!isValid) {
if (stripUnknown) {
internals.fastSplice(value, i);
--i;
--il;
continue;
}
errors.push(error('array.includes', { pos: i, value: item }, state.localize(path)));
if (prefs.abortEarly) {
return errors;
}
}
}
if (requireds.length) {
internals.fillMissedErrors(schema, errors, requireds, value, state, prefs);
}
if (ordereds.length) {
internals.fillOrderedErrors(schema, errors, ordereds, value, state, prefs);
if (!errors.length) {
internals.fillDefault(ordereds, value, state, prefs);
}
}
return errors.length ? errors : value;
},
priority: true,
manifest: false
},
length: {
method(limit) {
return this.$_addRule({ name: 'length', args: { limit }, operator: '=' });
},
validate(value, helpers, { limit }, { name, operator, args }) {
if (Common.compare(value.length, limit, operator)) {
return value;
}
return helpers.error('array.' + name, { limit: args.limit, value });
},
args: [
{
name: 'limit',
ref: true,
assert: Common.limit,
message: 'must be a positive integer'
}
]
},
max: {
method(limit) {
return this.$_addRule({ name: 'max', method: 'length', args: { limit }, operator: '<=' });
}
},
min: {
method(limit) {
return this.$_addRule({ name: 'min', method: 'length', args: { limit }, operator: '>=' });
}
},
ordered: {
method(...schemas) {
Common.verifyFlat(schemas, 'ordered');
const obj = this.$_addRule('items');
for (let i = 0; i < schemas.length; ++i) {
const type = Common.tryWithPath(() => this.$_compile(schemas[i]), i, { append: true });
internals.validateSingle(type, obj);
obj.$_mutateRegister(type);
obj.$_terms.ordered.push(type);
}
return obj.$_mutateRebuild();
}
},
single: {
method(enabled) {
const value = enabled === undefined ? true : !!enabled;
Assert(!value || !this._flags._arrayItems, 'Cannot specify single rule when array has array items');
return this.$_setFlag('single', value);
}
},
sort: {
method(options = {}) {
Common.assertOptions(options, ['by', 'order']);
const settings = {
order: options.order || 'ascending'
};
if (options.by) {
settings.by = Compile.ref(options.by, { ancestor: 0 });
Assert(!settings.by.ancestor, 'Cannot sort by ancestor');
}
return this.$_addRule({ name: 'sort', args: { options: settings } });
},
validate(value, { error, state, prefs, schema }, { options }) {
const { value: sorted, errors } = internals.sort(schema, value, options, state, prefs);
if (errors) {
return errors;
}
for (let i = 0; i < value.length; ++i) {
if (value[i] !== sorted[i]) {
return error('array.sort', { order: options.order, by: options.by ? options.by.key : 'value' });
}
}
return value;
},
convert: true
},
sparse: {
method(enabled) {
const value = enabled === undefined ? true : !!enabled;
if (this._flags.sparse === value) {
return this;
}
const obj = value ? this.clone() : this.$_addRule('items');
return obj.$_setFlag('sparse', value, { clone: false });
}
},
unique: {
method(comparator, options = {}) {
Assert(!comparator || typeof comparator === 'function' || typeof comparator === 'string', 'comparator must be a function or a string');
Common.assertOptions(options, ['ignoreUndefined', 'separator']);
const rule = { name: 'unique', args: { options, comparator } };
if (comparator) {
if (typeof comparator === 'string') {
const separator = Common.default(options.separator, '.');
rule.path = separator ? comparator.split(separator) : [comparator];
}
else {
rule.comparator = comparator;
}
}
return this.$_addRule(rule);
},
validate(value, { state, error, schema }, { comparator: raw, options }, { comparator, path }) {
const found = {
string: Object.create(null),
number: Object.create(null),
undefined: Object.create(null),
boolean: Object.create(null),
object: new Map(),
function: new Map(),
custom: new Map()
};
const compare = comparator || DeepEqual;
const ignoreUndefined = options.ignoreUndefined;
for (let i = 0; i < value.length; ++i) {
const item = path ? Reach(value[i], path) : value[i];
const records = comparator ? found.custom : found[typeof item];
Assert(records, 'Failed to find unique map container for type', typeof item);
if (records instanceof Map) {
const entries = records.entries();
let current;
while (!(current = entries.next()).done) {
if (compare(current.value[0], item)) {
const localState = state.localize([...state.path, i], [value, ...state.ancestors]);
const context = {
pos: i,
value: value[i],
dupePos: current.value[1],
dupeValue: value[current.value[1]]
};
if (path) {
context.path = raw;
}
return error('array.unique', context, localState);
}
}
records.set(item, i);
}
else {
if ((!ignoreUndefined || item !== undefined) &&
records[item] !== undefined) {
const context = {
pos: i,
value: value[i],
dupePos: records[item],
dupeValue: value[records[item]]
};
if (path) {
context.path = raw;
}
const localState = state.localize([...state.path, i], [value, ...state.ancestors]);
return error('array.unique', context, localState);
}
records[item] = i;
}
}
return value;
},
args: ['comparator', 'options'],
multi: true
}
},
cast: {
set: {
from: Array.isArray,
to(value, helpers) {
return new Set(value);
}
}
},
rebuild(schema) {
schema.$_terms._inclusions = [];
schema.$_terms._exclusions = [];
schema.$_terms._requireds = [];
for (const type of schema.$_terms.items) {
internals.validateSingle(type, schema);
if (type._flags.presence === 'required') {
schema.$_terms._requireds.push(type);
}
else if (type._flags.presence === 'forbidden') {
schema.$_terms._exclusions.push(type);
}
else {
schema.$_terms._inclusions.push(type);
}
}
for (const type of schema.$_terms.ordered) {
internals.validateSingle(type, schema);
}
},
manifest: {
build(obj, desc) {
if (desc.items) {
obj = obj.items(...desc.items);
}
if (desc.ordered) {
obj = obj.ordered(...desc.ordered);
}
return obj;
}
},
messages: {
'array.base': '{{#label}} must be an array',
'array.excludes': '{{#label}} contains an excluded value',
'array.hasKnown': '{{#label}} does not contain at least one required match for type {:#patternLabel}',
'array.hasUnknown': '{{#label}} does not contain at least one required match',
'array.includes': '{{#label}} does not match any of the allowed types',
'array.includesRequiredBoth': '{{#label}} does not contain {{#knownMisses}} and {{#unknownMisses}} other required value(s)',
'array.includesRequiredKnowns': '{{#label}} does not contain {{#knownMisses}}',
'array.includesRequiredUnknowns': '{{#label}} does not contain {{#unknownMisses}} required value(s)',
'array.length': '{{#label}} must contain {{#limit}} items',
'array.max': '{{#label}} must contain less than or equal to {{#limit}} items',
'array.min': '{{#label}} must contain at least {{#limit}} items',
'array.orderedLength': '{{#label}} must contain at most {{#limit}} items',
'array.sort': '{{#label}} must be sorted in {#order} order by {{#by}}',
'array.sort.mismatching': '{{#label}} cannot be sorted due to mismatching types',
'array.sort.unsupported': '{{#label}} cannot be sorted due to unsupported type {#type}',
'array.sparse': '{{#label}} must not be a sparse array item',
'array.unique': '{{#label}} contains a duplicate value'
}
});
// Helpers
internals.fillMissedErrors = function (schema, errors, requireds, value, state, prefs) {
const knownMisses = [];
let unknownMisses = 0;
for (const required of requireds) {
const label = required._flags.label;
if (label) {
knownMisses.push(label);
}
else {
++unknownMisses;
}
}
if (knownMisses.length) {
if (unknownMisses) {
errors.push(schema.$_createError('array.includesRequiredBoth', value, { knownMisses, unknownMisses }, state, prefs));
}
else {
errors.push(schema.$_createError('array.includesRequiredKnowns', value, { knownMisses }, state, prefs));
}
}
else {
errors.push(schema.$_createError('array.includesRequiredUnknowns', value, { unknownMisses }, state, prefs));
}
};
internals.fillOrderedErrors = function (schema, errors, ordereds, value, state, prefs) {
const requiredOrdereds = [];
for (const ordered of ordereds) {
if (ordered._flags.presence === 'required') {
requiredOrdereds.push(ordered);
}
}
if (requiredOrdereds.length) {
internals.fillMissedErrors(schema, errors, requiredOrdereds, value, state, prefs);
}
};
internals.fillDefault = function (ordereds, value, state, prefs) {
const overrides = [];
let trailingUndefined = true;
for (let i = ordereds.length - 1; i >= 0; --i) {
const ordered = ordereds[i];
const ancestors = [value, ...state.ancestors];
const override = ordered.$_validate(undefined, state.localize(state.path, ancestors, ordered), prefs).value;
if (trailingUndefined) {
if (override === undefined) {
continue;
}
trailingUndefined = false;
}
overrides.unshift(override);
}
if (overrides.length) {
value.push(...overrides);
}
};
internals.fastSplice = function (arr, i) {
let pos = i;
while (pos < arr.length) {
arr[pos++] = arr[pos];
}
--arr.length;
};
internals.validateSingle = function (type, obj) {
if (type.type === 'array' ||
type._flags._arrayItems) {
Assert(!obj._flags.single, 'Cannot specify array item with single rule enabled');
obj.$_setFlag('_arrayItems', true, { clone: false });
}
};
internals.sort = function (schema, value, settings, state, prefs) {
const order = settings.order === 'ascending' ? 1 : -1;
const aFirst = -1 * order;
const bFirst = order;
const sort = (a, b) => {
let compare = internals.compare(a, b, aFirst, bFirst);
if (compare !== null) {
return compare;
}
if (settings.by) {
a = settings.by.resolve(a, state, prefs);
b = settings.by.resolve(b, state, prefs);
}
compare = internals.compare(a, b, aFirst, bFirst);
if (compare !== null) {
return compare;
}
const type = typeof a;
if (type !== typeof b) {
throw schema.$_createError('array.sort.mismatching', value, null, state, prefs);
}
if (type !== 'number' &&
type !== 'string') {
throw schema.$_createError('array.sort.unsupported', value, { type }, state, prefs);
}
if (type === 'number') {
return (a - b) * order;
}
return a < b ? aFirst : bFirst;
};
try {
return { value: value.slice().sort(sort) };
}
catch (err) {
return { errors: err };
}
};
internals.compare = function (a, b, aFirst, bFirst) {
if (a === b) {
return 0;
}
if (a === undefined) {
return 1; // Always last regardless of sort order
}
if (b === undefined) {
return -1; // Always last regardless of sort order
}
if (a === null) {
return bFirst;
}
if (b === null) {
return aFirst;
}
return null;
};

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

@ -0,0 +1,98 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Any = require('./any');
const Common = require('../common');
const internals = {};
module.exports = Any.extend({
type: 'binary',
coerce: {
from: 'string',
method(value, { schema }) {
try {
return { value: Buffer.from(value, schema._flags.encoding) };
}
catch (ignoreErr) { }
}
},
validate(value, { error }) {
if (!Buffer.isBuffer(value)) {
return { value, errors: error('binary.base') };
}
},
rules: {
encoding: {
method(encoding) {
Assert(Buffer.isEncoding(encoding), 'Invalid encoding:', encoding);
return this.$_setFlag('encoding', encoding);
}
},
length: {
method(limit) {
return this.$_addRule({ name: 'length', method: 'length', args: { limit }, operator: '=' });
},
validate(value, helpers, { limit }, { name, operator, args }) {
if (Common.compare(value.length, limit, operator)) {
return value;
}
return helpers.error('binary.' + name, { limit: args.limit, value });
},
args: [
{
name: 'limit',
ref: true,
assert: Common.limit,
message: 'must be a positive integer'
}
]
},
max: {
method(limit) {
return this.$_addRule({ name: 'max', method: 'length', args: { limit }, operator: '<=' });
}
},
min: {
method(limit) {
return this.$_addRule({ name: 'min', method: 'length', args: { limit }, operator: '>=' });
}
}
},
cast: {
string: {
from: (value) => Buffer.isBuffer(value),
to(value, helpers) {
return value.toString();
}
}
},
messages: {
'binary.base': '{{#label}} must be a buffer or a string',
'binary.length': '{{#label}} must be {{#limit}} bytes',
'binary.max': '{{#label}} must be less than or equal to {{#limit}} bytes',
'binary.min': '{{#label}} must be at least {{#limit}} bytes'
}
});

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

@ -0,0 +1,150 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Any = require('./any');
const Common = require('../common');
const Values = require('../values');
const internals = {};
internals.isBool = function (value) {
return typeof value === 'boolean';
};
module.exports = Any.extend({
type: 'boolean',
flags: {
sensitive: { default: false }
},
terms: {
falsy: {
init: null,
manifest: 'values'
},
truthy: {
init: null,
manifest: 'values'
}
},
coerce(value, { schema }) {
if (typeof value === 'boolean') {
return;
}
if (typeof value === 'string') {
const normalized = schema._flags.sensitive ? value : value.toLowerCase();
value = normalized === 'true' ? true : (normalized === 'false' ? false : value);
}
if (typeof value !== 'boolean') {
value = schema.$_terms.truthy && schema.$_terms.truthy.has(value, null, null, !schema._flags.sensitive) ||
(schema.$_terms.falsy && schema.$_terms.falsy.has(value, null, null, !schema._flags.sensitive) ? false : value);
}
return { value };
},
validate(value, { error }) {
if (typeof value !== 'boolean') {
return { value, errors: error('boolean.base') };
}
},
rules: {
truthy: {
method(...values) {
Common.verifyFlat(values, 'truthy');
const obj = this.clone();
obj.$_terms.truthy = obj.$_terms.truthy || new Values();
for (let i = 0; i < values.length; ++i) {
const value = values[i];
Assert(value !== undefined, 'Cannot call truthy with undefined');
obj.$_terms.truthy.add(value);
}
return obj;
}
},
falsy: {
method(...values) {
Common.verifyFlat(values, 'falsy');
const obj = this.clone();
obj.$_terms.falsy = obj.$_terms.falsy || new Values();
for (let i = 0; i < values.length; ++i) {
const value = values[i];
Assert(value !== undefined, 'Cannot call falsy with undefined');
obj.$_terms.falsy.add(value);
}
return obj;
}
},
sensitive: {
method(enabled = true) {
return this.$_setFlag('sensitive', enabled);
}
}
},
cast: {
number: {
from: internals.isBool,
to(value, helpers) {
return value ? 1 : 0;
}
},
string: {
from: internals.isBool,
to(value, helpers) {
return value ? 'true' : 'false';
}
}
},
manifest: {
build(obj, desc) {
if (desc.truthy) {
obj = obj.truthy(...desc.truthy);
}
if (desc.falsy) {
obj = obj.falsy(...desc.falsy);
}
return obj;
}
},
messages: {
'boolean.base': '{{#label}} must be a boolean'
}
});

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

@ -0,0 +1,233 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Any = require('./any');
const Common = require('../common');
const Template = require('../template');
const internals = {};
internals.isDate = function (value) {
return value instanceof Date;
};
module.exports = Any.extend({
type: 'date',
coerce: {
from: ['number', 'string'],
method(value, { schema }) {
return { value: internals.parse(value, schema._flags.format) || value };
}
},
validate(value, { schema, error, prefs }) {
if (value instanceof Date &&
!isNaN(value.getTime())) {
return;
}
const format = schema._flags.format;
if (!prefs.convert ||
!format ||
typeof value !== 'string') {
return { value, errors: error('date.base') };
}
return { value, errors: error('date.format', { format }) };
},
rules: {
compare: {
method: false,
validate(value, helpers, { date }, { name, operator, args }) {
const to = date === 'now' ? Date.now() : date.getTime();
if (Common.compare(value.getTime(), to, operator)) {
return value;
}
return helpers.error('date.' + name, { limit: args.date, value });
},
args: [
{
name: 'date',
ref: true,
normalize: (date) => {
return date === 'now' ? date : internals.parse(date);
},
assert: (date) => date !== null,
message: 'must have a valid date format'
}
]
},
format: {
method(format) {
Assert(['iso', 'javascript', 'unix'].includes(format), 'Unknown date format', format);
return this.$_setFlag('format', format);
}
},
greater: {
method(date) {
return this.$_addRule({ name: 'greater', method: 'compare', args: { date }, operator: '>' });
}
},
iso: {
method() {
return this.format('iso');
}
},
less: {
method(date) {
return this.$_addRule({ name: 'less', method: 'compare', args: { date }, operator: '<' });
}
},
max: {
method(date) {
return this.$_addRule({ name: 'max', method: 'compare', args: { date }, operator: '<=' });
}
},
min: {
method(date) {
return this.$_addRule({ name: 'min', method: 'compare', args: { date }, operator: '>=' });
}
},
timestamp: {
method(type = 'javascript') {
Assert(['javascript', 'unix'].includes(type), '"type" must be one of "javascript, unix"');
return this.format(type);
}
}
},
cast: {
number: {
from: internals.isDate,
to(value, helpers) {
return value.getTime();
}
},
string: {
from: internals.isDate,
to(value, { prefs }) {
return Template.date(value, prefs);
}
}
},
messages: {
'date.base': '{{#label}} must be a valid date',
'date.format': '{{#label}} must be in {msg("date.format." + #format) || #format} format',
'date.greater': '{{#label}} must be greater than {{:#limit}}',
'date.less': '{{#label}} must be less than {{:#limit}}',
'date.max': '{{#label}} must be less than or equal to {{:#limit}}',
'date.min': '{{#label}} must be greater than or equal to {{:#limit}}',
// Messages used in date.format
'date.format.iso': 'ISO 8601 date',
'date.format.javascript': 'timestamp or number of milliseconds',
'date.format.unix': 'timestamp or number of seconds'
}
});
// Helpers
internals.parse = function (value, format) {
if (value instanceof Date) {
return value;
}
if (typeof value !== 'string' &&
(isNaN(value) || !isFinite(value))) {
return null;
}
if (/^\s*$/.test(value)) {
return null;
}
// ISO
if (format === 'iso') {
if (!Common.isIsoDate(value)) {
return null;
}
return internals.date(value.toString());
}
// Normalize number string
const original = value;
if (typeof value === 'string' &&
/^[+-]?\d+(\.\d+)?$/.test(value)) {
value = parseFloat(value);
}
// Timestamp
if (format) {
if (format === 'javascript') {
return internals.date(1 * value); // Casting to number
}
if (format === 'unix') {
return internals.date(1000 * value);
}
if (typeof original === 'string') {
return null;
}
}
// Plain
return internals.date(value);
};
internals.date = function (value) {
const date = new Date(value);
if (!isNaN(date.getTime())) {
return date;
}
return null;
};

93
node_modules/joi/lib/types/function.js generated vendored Normal file
View File

@ -0,0 +1,93 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Keys = require('./keys');
const internals = {};
module.exports = Keys.extend({
type: 'function',
properties: {
typeof: 'function'
},
rules: {
arity: {
method(n) {
Assert(Number.isSafeInteger(n) && n >= 0, 'n must be a positive integer');
return this.$_addRule({ name: 'arity', args: { n } });
},
validate(value, helpers, { n }) {
if (value.length === n) {
return value;
}
return helpers.error('function.arity', { n });
}
},
class: {
method() {
return this.$_addRule('class');
},
validate(value, helpers) {
if ((/^\s*class\s/).test(value.toString())) {
return value;
}
return helpers.error('function.class', { value });
}
},
minArity: {
method(n) {
Assert(Number.isSafeInteger(n) && n > 0, 'n must be a strict positive integer');
return this.$_addRule({ name: 'minArity', args: { n } });
},
validate(value, helpers, { n }) {
if (value.length >= n) {
return value;
}
return helpers.error('function.minArity', { n });
}
},
maxArity: {
method(n) {
Assert(Number.isSafeInteger(n) && n >= 0, 'n must be a positive integer');
return this.$_addRule({ name: 'maxArity', args: { n } });
},
validate(value, helpers, { n }) {
if (value.length <= n) {
return value;
}
return helpers.error('function.maxArity', { n });
}
}
},
messages: {
'function.arity': '{{#label}} must have an arity of {{#n}}',
'function.class': '{{#label}} must be a class',
'function.maxArity': '{{#label}} must have an arity lesser or equal to {{#n}}',
'function.minArity': '{{#label}} must have an arity greater or equal to {{#n}}'
}
});

1067
node_modules/joi/lib/types/keys.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

168
node_modules/joi/lib/types/link.js generated vendored Normal file
View File

@ -0,0 +1,168 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Any = require('./any');
const Common = require('../common');
const Compile = require('../compile');
const Errors = require('../errors');
const internals = {};
module.exports = Any.extend({
type: 'link',
properties: {
schemaChain: true
},
terms: {
link: { init: null, manifest: 'single', register: false }
},
args(schema, ref) {
return schema.ref(ref);
},
validate(value, { schema, state, prefs }) {
Assert(schema.$_terms.link, 'Uninitialized link schema');
const linked = internals.generate(schema, value, state, prefs);
const ref = schema.$_terms.link[0].ref;
return linked.$_validate(value, state.nest(linked, `link:${ref.display}:${linked.type}`), prefs);
},
generate(schema, value, state, prefs) {
return internals.generate(schema, value, state, prefs);
},
rules: {
ref: {
method(ref) {
Assert(!this.$_terms.link, 'Cannot reinitialize schema');
ref = Compile.ref(ref);
Assert(ref.type === 'value' || ref.type === 'local', 'Invalid reference type:', ref.type);
Assert(ref.type === 'local' || ref.ancestor === 'root' || ref.ancestor > 0, 'Link cannot reference itself');
const obj = this.clone();
obj.$_terms.link = [{ ref }];
return obj;
}
},
relative: {
method(enabled = true) {
return this.$_setFlag('relative', enabled);
}
}
},
overrides: {
concat(source) {
Assert(this.$_terms.link, 'Uninitialized link schema');
Assert(Common.isSchema(source), 'Invalid schema object');
Assert(source.type !== 'link', 'Cannot merge type link with another link');
const obj = this.clone();
if (!obj.$_terms.whens) {
obj.$_terms.whens = [];
}
obj.$_terms.whens.push({ concat: source });
return obj.$_mutateRebuild();
}
},
manifest: {
build(obj, desc) {
Assert(desc.link, 'Invalid link description missing link');
return obj.ref(desc.link);
}
}
});
// Helpers
internals.generate = function (schema, value, state, prefs) {
let linked = state.mainstay.links.get(schema);
if (linked) {
return linked._generate(value, state, prefs).schema;
}
const ref = schema.$_terms.link[0].ref;
const { perspective, path } = internals.perspective(ref, state);
internals.assert(perspective, 'which is outside of schema boundaries', ref, schema, state, prefs);
try {
linked = path.length ? perspective.$_reach(path) : perspective;
}
catch (ignoreErr) {
internals.assert(false, 'to non-existing schema', ref, schema, state, prefs);
}
internals.assert(linked.type !== 'link', 'which is another link', ref, schema, state, prefs);
if (!schema._flags.relative) {
state.mainstay.links.set(schema, linked);
}
return linked._generate(value, state, prefs).schema;
};
internals.perspective = function (ref, state) {
if (ref.type === 'local') {
for (const { schema, key } of state.schemas) { // From parent to root
const id = schema._flags.id || key;
if (id === ref.path[0]) {
return { perspective: schema, path: ref.path.slice(1) };
}
if (schema.$_terms.shared) {
for (const shared of schema.$_terms.shared) {
if (shared._flags.id === ref.path[0]) {
return { perspective: shared, path: ref.path.slice(1) };
}
}
}
}
return { perspective: null, path: null };
}
if (ref.ancestor === 'root') {
return { perspective: state.schemas[state.schemas.length - 1].schema, path: ref.path };
}
return { perspective: state.schemas[ref.ancestor] && state.schemas[ref.ancestor].schema, path: ref.path };
};
internals.assert = function (condition, message, ref, schema, state, prefs) {
if (condition) { // Manual check to avoid generating error message on success
return;
}
Assert(false, `"${Errors.label(schema._flags, state, prefs)}" contains link reference "${ref.display}" ${message}`);
};

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

@ -0,0 +1,336 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Any = require('./any');
const Common = require('../common');
const internals = {
numberRx: /^\s*[+-]?(?:(?:\d+(?:\.\d*)?)|(?:\.\d+))(?:e([+-]?\d+))?\s*$/i,
precisionRx: /(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/,
exponentialPartRegex: /[eE][+-]?\d+$/,
leadingSignAndZerosRegex: /^[+-]?(0*)?/,
dotRegex: /\./,
trailingZerosRegex: /0+$/
};
module.exports = Any.extend({
type: 'number',
flags: {
unsafe: { default: false }
},
coerce: {
from: 'string',
method(value, { schema, error }) {
const matches = value.match(internals.numberRx);
if (!matches) {
return;
}
value = value.trim();
const result = { value: parseFloat(value) };
if (result.value === 0) {
result.value = 0; // -0
}
if (!schema._flags.unsafe) {
if (value.match(/e/i)) {
if (internals.extractSignificantDigits(value) !== internals.extractSignificantDigits(String(result.value))) {
result.errors = error('number.unsafe');
return result;
}
}
else {
const string = result.value.toString();
if (string.match(/e/i)) {
return result;
}
if (string !== internals.normalizeDecimal(value)) {
result.errors = error('number.unsafe');
return result;
}
}
}
return result;
}
},
validate(value, { schema, error, prefs }) {
if (value === Infinity ||
value === -Infinity) {
return { value, errors: error('number.infinity') };
}
if (!Common.isNumber(value)) {
return { value, errors: error('number.base') };
}
const result = { value };
if (prefs.convert) {
const rule = schema.$_getRule('precision');
if (rule) {
const precision = Math.pow(10, rule.args.limit); // This is conceptually equivalent to using toFixed but it should be much faster
result.value = Math.round(result.value * precision) / precision;
}
}
if (result.value === 0) {
result.value = 0; // -0
}
if (!schema._flags.unsafe &&
(value > Number.MAX_SAFE_INTEGER || value < Number.MIN_SAFE_INTEGER)) {
result.errors = error('number.unsafe');
}
return result;
},
rules: {
compare: {
method: false,
validate(value, helpers, { limit }, { name, operator, args }) {
if (Common.compare(value, limit, operator)) {
return value;
}
return helpers.error('number.' + name, { limit: args.limit, value });
},
args: [
{
name: 'limit',
ref: true,
assert: Common.isNumber,
message: 'must be a number'
}
]
},
greater: {
method(limit) {
return this.$_addRule({ name: 'greater', method: 'compare', args: { limit }, operator: '>' });
}
},
integer: {
method() {
return this.$_addRule('integer');
},
validate(value, helpers) {
if (Math.trunc(value) - value === 0) {
return value;
}
return helpers.error('number.integer');
}
},
less: {
method(limit) {
return this.$_addRule({ name: 'less', method: 'compare', args: { limit }, operator: '<' });
}
},
max: {
method(limit) {
return this.$_addRule({ name: 'max', method: 'compare', args: { limit }, operator: '<=' });
}
},
min: {
method(limit) {
return this.$_addRule({ name: 'min', method: 'compare', args: { limit }, operator: '>=' });
}
},
multiple: {
method(base) {
return this.$_addRule({ name: 'multiple', args: { base } });
},
validate(value, helpers, { base }, options) {
if (value * (1 / base) % 1 === 0) {
return value;
}
return helpers.error('number.multiple', { multiple: options.args.base, value });
},
args: [
{
name: 'base',
ref: true,
assert: (value) => typeof value === 'number' && isFinite(value) && value > 0,
message: 'must be a positive number'
}
],
multi: true
},
negative: {
method() {
return this.sign('negative');
}
},
port: {
method() {
return this.$_addRule('port');
},
validate(value, helpers) {
if (Number.isSafeInteger(value) &&
value >= 0 &&
value <= 65535) {
return value;
}
return helpers.error('number.port');
}
},
positive: {
method() {
return this.sign('positive');
}
},
precision: {
method(limit) {
Assert(Number.isSafeInteger(limit), 'limit must be an integer');
return this.$_addRule({ name: 'precision', args: { limit } });
},
validate(value, helpers, { limit }) {
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 helpers.error('number.precision', { limit, value });
},
convert: true
},
sign: {
method(sign) {
Assert(['negative', 'positive'].includes(sign), 'Invalid sign', sign);
return this.$_addRule({ name: 'sign', args: { sign } });
},
validate(value, helpers, { sign }) {
if (sign === 'negative' && value < 0 ||
sign === 'positive' && value > 0) {
return value;
}
return helpers.error(`number.${sign}`);
}
},
unsafe: {
method(enabled = true) {
Assert(typeof enabled === 'boolean', 'enabled must be a boolean');
return this.$_setFlag('unsafe', enabled);
}
}
},
cast: {
string: {
from: (value) => typeof value === 'number',
to(value, helpers) {
return value.toString();
}
}
},
messages: {
'number.base': '{{#label}} must be a number',
'number.greater': '{{#label}} must be greater than {{#limit}}',
'number.infinity': '{{#label}} cannot be infinity',
'number.integer': '{{#label}} must be an integer',
'number.less': '{{#label}} must be less than {{#limit}}',
'number.max': '{{#label}} must be less than or equal to {{#limit}}',
'number.min': '{{#label}} must be greater than or equal to {{#limit}}',
'number.multiple': '{{#label}} must be a multiple of {{#multiple}}',
'number.negative': '{{#label}} must be a negative number',
'number.port': '{{#label}} must be a valid port',
'number.positive': '{{#label}} must be a positive number',
'number.precision': '{{#label}} must have no more than {{#limit}} decimal places',
'number.unsafe': '{{#label}} must be a safe number'
}
});
// Helpers
internals.extractSignificantDigits = function (value) {
return value
.replace(internals.exponentialPartRegex, '')
.replace(internals.dotRegex, '')
.replace(internals.trailingZerosRegex, '')
.replace(internals.leadingSignAndZerosRegex, '');
};
internals.normalizeDecimal = function (str) {
str = str
// Remove leading plus signs
.replace(/^\+/, '')
// Remove trailing zeros if there is a decimal point and unecessary decimal points
.replace(/\.0*$/, '')
// Add a integer 0 if the numbers starts with a decimal point
.replace(/^(-?)\.([^\.]*)$/, '$10.$2')
// Remove leading zeros
.replace(/^(-?)0+([0-9])/, '$1$2');
if (str.includes('.') &&
str.endsWith('0')) {
str = str.replace(/0+$/, '');
}
if (str === '-0') {
return '0';
}
return str;
};

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

@ -0,0 +1,22 @@
'use strict';
const Keys = require('./keys');
const internals = {};
module.exports = Keys.extend({
type: 'object',
cast: {
map: {
from: (value) => value && typeof value === 'object',
to(value, helpers) {
return new Map(Object.entries(value));
}
}
}
});

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

@ -0,0 +1,828 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Domain = require('@sideway/address/lib/domain');
const Email = require('@sideway/address/lib/email');
const Ip = require('@sideway/address/lib/ip');
const EscapeRegex = require('@hapi/hoek/lib/escapeRegex');
const Tlds = require('@sideway/address/lib/tlds');
const Uri = require('@sideway/address/lib/uri');
const Any = require('./any');
const Common = require('../common');
const internals = {
tlds: Tlds instanceof Set ? { tlds: { allow: Tlds, deny: null } } : false, // $lab:coverage:ignore$
base64Regex: {
// paddingRequired
true: {
// urlSafe
true: /^(?:[\w\-]{2}[\w\-]{2})*(?:[\w\-]{2}==|[\w\-]{3}=)?$/,
false: /^(?:[A-Za-z0-9+\/]{2}[A-Za-z0-9+\/]{2})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?$/
},
false: {
true: /^(?:[\w\-]{2}[\w\-]{2})*(?:[\w\-]{2}(==)?|[\w\-]{3}=?)?$/,
false: /^(?:[A-Za-z0-9+\/]{2}[A-Za-z0-9+\/]{2})*(?:[A-Za-z0-9+\/]{2}(==)?|[A-Za-z0-9+\/]{3}=?)?$/
}
},
dataUriRegex: /^data:[\w+.-]+\/[\w+.-]+;((charset=[\w-]+|base64),)?(.*)$/,
hexRegex: /^[a-f0-9]+$/i,
ipRegex: Ip.regex({ cidr: 'forbidden' }).regex,
isoDurationRegex: /^P(?!$)(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?$/,
guidBrackets: {
'{': '}', '[': ']', '(': ')', '': ''
},
guidVersions: {
uuidv1: '1',
uuidv2: '2',
uuidv3: '3',
uuidv4: '4',
uuidv5: '5'
},
guidSeparators: new Set([undefined, true, false, '-', ':']),
normalizationForms: ['NFC', 'NFD', 'NFKC', 'NFKD']
};
module.exports = Any.extend({
type: 'string',
flags: {
insensitive: { default: false },
truncate: { default: false }
},
terms: {
replacements: { init: null }
},
coerce: {
from: 'string',
method(value, { schema, state, prefs }) {
const normalize = schema.$_getRule('normalize');
if (normalize) {
value = value.normalize(normalize.args.form);
}
const casing = schema.$_getRule('case');
if (casing) {
value = casing.args.direction === 'upper' ? value.toLocaleUpperCase() : value.toLocaleLowerCase();
}
const trim = schema.$_getRule('trim');
if (trim &&
trim.args.enabled) {
value = value.trim();
}
if (schema.$_terms.replacements) {
for (const replacement of schema.$_terms.replacements) {
value = value.replace(replacement.pattern, replacement.replacement);
}
}
const hex = schema.$_getRule('hex');
if (hex &&
hex.args.options.byteAligned &&
value.length % 2 !== 0) {
value = `0${value}`;
}
if (schema.$_getRule('isoDate')) {
const iso = internals.isoDate(value);
if (iso) {
value = iso;
}
}
if (schema._flags.truncate) {
const rule = schema.$_getRule('max');
if (rule) {
let limit = rule.args.limit;
if (Common.isResolvable(limit)) {
limit = limit.resolve(value, state, prefs);
if (!Common.limit(limit)) {
return { value, errors: schema.$_createError('any.ref', limit, { ref: rule.args.limit, arg: 'limit', reason: 'must be a positive integer' }, state, prefs) };
}
}
value = value.slice(0, limit);
}
}
return { value };
}
},
validate(value, { schema, error }) {
if (typeof value !== 'string') {
return { value, errors: error('string.base') };
}
if (value === '') {
const min = schema.$_getRule('min');
if (min &&
min.args.limit === 0) {
return;
}
return { value, errors: error('string.empty') };
}
},
rules: {
alphanum: {
method() {
return this.$_addRule('alphanum');
},
validate(value, helpers) {
if (/^[a-zA-Z0-9]+$/.test(value)) {
return value;
}
return helpers.error('string.alphanum');
}
},
base64: {
method(options = {}) {
Common.assertOptions(options, ['paddingRequired', 'urlSafe']);
options = { urlSafe: false, paddingRequired: true, ...options };
Assert(typeof options.paddingRequired === 'boolean', 'paddingRequired must be boolean');
Assert(typeof options.urlSafe === 'boolean', 'urlSafe must be boolean');
return this.$_addRule({ name: 'base64', args: { options } });
},
validate(value, helpers, { options }) {
const regex = internals.base64Regex[options.paddingRequired][options.urlSafe];
if (regex.test(value)) {
return value;
}
return helpers.error('string.base64');
}
},
case: {
method(direction) {
Assert(['lower', 'upper'].includes(direction), 'Invalid case:', direction);
return this.$_addRule({ name: 'case', args: { direction } });
},
validate(value, helpers, { direction }) {
if (direction === 'lower' && value === value.toLocaleLowerCase() ||
direction === 'upper' && value === value.toLocaleUpperCase()) {
return value;
}
return helpers.error(`string.${direction}case`);
},
convert: true
},
creditCard: {
method() {
return this.$_addRule('creditCard');
},
validate(value, helpers) {
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;
}
if (sum > 0 &&
sum % 10 === 0) {
return value;
}
return helpers.error('string.creditCard');
}
},
dataUri: {
method(options = {}) {
Common.assertOptions(options, ['paddingRequired']);
options = { paddingRequired: true, ...options };
Assert(typeof options.paddingRequired === 'boolean', 'paddingRequired must be boolean');
return this.$_addRule({ name: 'dataUri', args: { options } });
},
validate(value, helpers, { options }) {
const matches = value.match(internals.dataUriRegex);
if (matches) {
if (!matches[2]) {
return value;
}
if (matches[2] !== 'base64') {
return value;
}
const base64regex = internals.base64Regex[options.paddingRequired].false;
if (base64regex.test(matches[3])) {
return value;
}
}
return helpers.error('string.dataUri');
}
},
domain: {
method(options) {
if (options) {
Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']);
}
const address = internals.addressOptions(options);
return this.$_addRule({ name: 'domain', args: { options }, address });
},
validate(value, helpers, args, { address }) {
if (Domain.isValid(value, address)) {
return value;
}
return helpers.error('string.domain');
}
},
email: {
method(options = {}) {
Common.assertOptions(options, ['allowFullyQualified', 'allowUnicode', 'ignoreLength', 'maxDomainSegments', 'minDomainSegments', 'multiple', 'separator', 'tlds']);
Assert(options.multiple === undefined || typeof options.multiple === 'boolean', 'multiple option must be an boolean');
const address = internals.addressOptions(options);
const regex = new RegExp(`\\s*[${options.separator ? EscapeRegex(options.separator) : ','}]\\s*`);
return this.$_addRule({ name: 'email', args: { options }, regex, address });
},
validate(value, helpers, { options }, { regex, address }) {
const emails = options.multiple ? value.split(regex) : [value];
const invalids = [];
for (const email of emails) {
if (!Email.isValid(email, address)) {
invalids.push(email);
}
}
if (!invalids.length) {
return value;
}
return helpers.error('string.email', { value, invalids });
}
},
guid: {
alias: 'uuid',
method(options = {}) {
Common.assertOptions(options, ['version', 'separator']);
let versionNumbers = '';
if (options.version) {
const versions = [].concat(options.version);
Assert(versions.length >= 1, 'version must have at least 1 valid version specified');
const set = new Set();
for (let i = 0; i < versions.length; ++i) {
const version = versions[i];
Assert(typeof version === 'string', 'version at position ' + i + ' must be a string');
const versionNumber = internals.guidVersions[version.toLowerCase()];
Assert(versionNumber, 'version at position ' + i + ' must be one of ' + Object.keys(internals.guidVersions).join(', '));
Assert(!set.has(versionNumber), 'version at position ' + i + ' must not be a duplicate');
versionNumbers += versionNumber;
set.add(versionNumber);
}
}
Assert(internals.guidSeparators.has(options.separator), 'separator must be one of true, false, "-", or ":"');
const separator = options.separator === undefined ? '[:-]?' :
options.separator === true ? '[:-]' :
options.separator === false ? '[]?' : `\\${options.separator}`;
const regex = new RegExp(`^([\\[{\\(]?)[0-9A-F]{8}(${separator})[0-9A-F]{4}\\2?[${versionNumbers || '0-9A-F'}][0-9A-F]{3}\\2?[${versionNumbers ? '89AB' : '0-9A-F'}][0-9A-F]{3}\\2?[0-9A-F]{12}([\\]}\\)]?)$`, 'i');
return this.$_addRule({ name: 'guid', args: { options }, regex });
},
validate(value, helpers, args, { regex }) {
const results = regex.exec(value);
if (!results) {
return helpers.error('string.guid');
}
// Matching braces
if (internals.guidBrackets[results[1]] !== results[results.length - 1]) {
return helpers.error('string.guid');
}
return value;
}
},
hex: {
method(options = {}) {
Common.assertOptions(options, ['byteAligned']);
options = { byteAligned: false, ...options };
Assert(typeof options.byteAligned === 'boolean', 'byteAligned must be boolean');
return this.$_addRule({ name: 'hex', args: { options } });
},
validate(value, helpers, { options }) {
if (!internals.hexRegex.test(value)) {
return helpers.error('string.hex');
}
if (options.byteAligned &&
value.length % 2 !== 0) {
return helpers.error('string.hexAlign');
}
return value;
}
},
hostname: {
method() {
return this.$_addRule('hostname');
},
validate(value, helpers) {
if (Domain.isValid(value, { minDomainSegments: 1 }) ||
internals.ipRegex.test(value)) {
return value;
}
return helpers.error('string.hostname');
}
},
insensitive: {
method() {
return this.$_setFlag('insensitive', true);
}
},
ip: {
method(options = {}) {
Common.assertOptions(options, ['cidr', 'version']);
const { cidr, versions, regex } = Ip.regex(options);
const version = options.version ? versions : undefined;
return this.$_addRule({ name: 'ip', args: { options: { cidr, version } }, regex });
},
validate(value, helpers, { options }, { regex }) {
if (regex.test(value)) {
return value;
}
if (options.version) {
return helpers.error('string.ipVersion', { value, cidr: options.cidr, version: options.version });
}
return helpers.error('string.ip', { value, cidr: options.cidr });
}
},
isoDate: {
method() {
return this.$_addRule('isoDate');
},
validate(value, { error }) {
if (internals.isoDate(value)) {
return value;
}
return error('string.isoDate');
}
},
isoDuration: {
method() {
return this.$_addRule('isoDuration');
},
validate(value, helpers) {
if (internals.isoDurationRegex.test(value)) {
return value;
}
return helpers.error('string.isoDuration');
}
},
length: {
method(limit, encoding) {
return internals.length(this, 'length', limit, '=', encoding);
},
validate(value, helpers, { limit, encoding }, { name, operator, args }) {
const length = encoding ? Buffer && Buffer.byteLength(value, encoding) : value.length; // $lab:coverage:ignore$
if (Common.compare(length, limit, operator)) {
return value;
}
return helpers.error('string.' + name, { limit: args.limit, value, encoding });
},
args: [
{
name: 'limit',
ref: true,
assert: Common.limit,
message: 'must be a positive integer'
},
'encoding'
]
},
lowercase: {
method() {
return this.case('lower');
}
},
max: {
method(limit, encoding) {
return internals.length(this, 'max', limit, '<=', encoding);
},
args: ['limit', 'encoding']
},
min: {
method(limit, encoding) {
return internals.length(this, 'min', limit, '>=', encoding);
},
args: ['limit', 'encoding']
},
normalize: {
method(form = 'NFC') {
Assert(internals.normalizationForms.includes(form), 'normalization form must be one of ' + internals.normalizationForms.join(', '));
return this.$_addRule({ name: 'normalize', args: { form } });
},
validate(value, { error }, { form }) {
if (value === value.normalize(form)) {
return value;
}
return error('string.normalize', { value, form });
},
convert: true
},
pattern: {
alias: 'regex',
method(regex, options = {}) {
Assert(regex instanceof RegExp, 'regex must be a RegExp');
Assert(!regex.flags.includes('g') && !regex.flags.includes('y'), 'regex should not use global or sticky mode');
if (typeof options === 'string') {
options = { name: options };
}
Common.assertOptions(options, ['invert', 'name']);
const errorCode = ['string.pattern', options.invert ? '.invert' : '', options.name ? '.name' : '.base'].join('');
return this.$_addRule({ name: 'pattern', args: { regex, options }, errorCode });
},
validate(value, helpers, { regex, options }, { errorCode }) {
const patternMatch = regex.test(value);
if (patternMatch ^ options.invert) {
return value;
}
return helpers.error(errorCode, { name: options.name, regex, value });
},
args: ['regex', 'options'],
multi: true
},
replace: {
method(pattern, replacement) {
if (typeof pattern === 'string') {
pattern = new RegExp(EscapeRegex(pattern), 'g');
}
Assert(pattern instanceof RegExp, 'pattern must be a RegExp');
Assert(typeof replacement === 'string', 'replacement must be a String');
const obj = this.clone();
if (!obj.$_terms.replacements) {
obj.$_terms.replacements = [];
}
obj.$_terms.replacements.push({ pattern, replacement });
return obj;
}
},
token: {
method() {
return this.$_addRule('token');
},
validate(value, helpers) {
if (/^\w+$/.test(value)) {
return value;
}
return helpers.error('string.token');
}
},
trim: {
method(enabled = true) {
Assert(typeof enabled === 'boolean', 'enabled must be a boolean');
return this.$_addRule({ name: 'trim', args: { enabled } });
},
validate(value, helpers, { enabled }) {
if (!enabled ||
value === value.trim()) {
return value;
}
return helpers.error('string.trim');
},
convert: true
},
truncate: {
method(enabled = true) {
Assert(typeof enabled === 'boolean', 'enabled must be a boolean');
return this.$_setFlag('truncate', enabled);
}
},
uppercase: {
method() {
return this.case('upper');
}
},
uri: {
method(options = {}) {
Common.assertOptions(options, ['allowRelative', 'allowQuerySquareBrackets', 'domain', 'relativeOnly', 'scheme']);
if (options.domain) {
Common.assertOptions(options.domain, ['allowFullyQualified', 'allowUnicode', 'maxDomainSegments', 'minDomainSegments', 'tlds']);
}
const { regex, scheme } = Uri.regex(options);
const domain = options.domain ? internals.addressOptions(options.domain) : null;
return this.$_addRule({ name: 'uri', args: { options }, regex, domain, scheme });
},
validate(value, helpers, { options }, { regex, domain, scheme }) {
if (['http:/', 'https:/'].includes(value)) { // scheme:/ is technically valid but makes no sense
return helpers.error('string.uri');
}
const match = regex.exec(value);
if (match) {
const matched = match[1] || match[2];
if (domain &&
(!options.allowRelative || matched) &&
!Domain.isValid(matched, domain)) {
return helpers.error('string.domain', { value: matched });
}
return value;
}
if (options.relativeOnly) {
return helpers.error('string.uriRelativeOnly');
}
if (options.scheme) {
return helpers.error('string.uriCustomScheme', { scheme, value });
}
return helpers.error('string.uri');
}
}
},
manifest: {
build(obj, desc) {
if (desc.replacements) {
for (const { pattern, replacement } of desc.replacements) {
obj = obj.replace(pattern, replacement);
}
}
return obj;
}
},
messages: {
'string.alphanum': '{{#label}} must only contain alpha-numeric characters',
'string.base': '{{#label}} must be a string',
'string.base64': '{{#label}} must be a valid base64 string',
'string.creditCard': '{{#label}} must be a credit card',
'string.dataUri': '{{#label}} must be a valid dataUri string',
'string.domain': '{{#label}} must contain a valid domain name',
'string.email': '{{#label}} must be a valid email',
'string.empty': '{{#label}} is not allowed to be empty',
'string.guid': '{{#label}} must be a valid GUID',
'string.hex': '{{#label}} must only contain hexadecimal characters',
'string.hexAlign': '{{#label}} hex decoded representation must be byte aligned',
'string.hostname': '{{#label}} must be a valid hostname',
'string.ip': '{{#label}} must be a valid ip address with a {{#cidr}} CIDR',
'string.ipVersion': '{{#label}} must be a valid ip address of one of the following versions {{#version}} with a {{#cidr}} CIDR',
'string.isoDate': '{{#label}} must be in iso format',
'string.isoDuration': '{{#label}} must be a valid ISO 8601 duration',
'string.length': '{{#label}} length must be {{#limit}} characters long',
'string.lowercase': '{{#label}} must only contain lowercase characters',
'string.max': '{{#label}} length must be less than or equal to {{#limit}} characters long',
'string.min': '{{#label}} length must be at least {{#limit}} characters long',
'string.normalize': '{{#label}} must be unicode normalized in the {{#form}} form',
'string.token': '{{#label}} must only contain alpha-numeric and underscore characters',
'string.pattern.base': '{{#label}} with value {:[.]} fails to match the required pattern: {{#regex}}',
'string.pattern.name': '{{#label}} with value {:[.]} fails to match the {{#name}} pattern',
'string.pattern.invert.base': '{{#label}} with value {:[.]} matches the inverted pattern: {{#regex}}',
'string.pattern.invert.name': '{{#label}} with value {:[.]} matches the inverted {{#name}} pattern',
'string.trim': '{{#label}} must not have leading or trailing whitespace',
'string.uri': '{{#label}} must be a valid uri',
'string.uriCustomScheme': '{{#label}} must be a valid uri with a scheme matching the {{#scheme}} pattern',
'string.uriRelativeOnly': '{{#label}} must be a valid relative uri',
'string.uppercase': '{{#label}} must only contain uppercase characters'
}
});
// Helpers
internals.addressOptions = function (options) {
if (!options) {
return options;
}
// minDomainSegments
Assert(options.minDomainSegments === undefined ||
Number.isSafeInteger(options.minDomainSegments) && options.minDomainSegments > 0, 'minDomainSegments must be a positive integer');
// maxDomainSegments
Assert(options.maxDomainSegments === undefined ||
Number.isSafeInteger(options.maxDomainSegments) && options.maxDomainSegments > 0, 'maxDomainSegments must be a positive integer');
// tlds
if (options.tlds === false) {
return options;
}
if (options.tlds === true ||
options.tlds === undefined) {
Assert(internals.tlds, 'Built-in TLD list disabled');
return Object.assign({}, options, internals.tlds);
}
Assert(typeof options.tlds === 'object', 'tlds must be true, false, or an object');
const deny = options.tlds.deny;
if (deny) {
if (Array.isArray(deny)) {
options = Object.assign({}, options, { tlds: { deny: new Set(deny) } });
}
Assert(options.tlds.deny instanceof Set, 'tlds.deny must be an array, Set, or boolean');
Assert(!options.tlds.allow, 'Cannot specify both tlds.allow and tlds.deny lists');
internals.validateTlds(options.tlds.deny, 'tlds.deny');
return options;
}
const allow = options.tlds.allow;
if (!allow) {
return options;
}
if (allow === true) {
Assert(internals.tlds, 'Built-in TLD list disabled');
return Object.assign({}, options, internals.tlds);
}
if (Array.isArray(allow)) {
options = Object.assign({}, options, { tlds: { allow: new Set(allow) } });
}
Assert(options.tlds.allow instanceof Set, 'tlds.allow must be an array, Set, or boolean');
internals.validateTlds(options.tlds.allow, 'tlds.allow');
return options;
};
internals.validateTlds = function (set, source) {
for (const tld of set) {
Assert(Domain.isValid(tld, { minDomainSegments: 1, maxDomainSegments: 1 }), `${source} must contain valid top level domain names`);
}
};
internals.isoDate = function (value) {
if (!Common.isIsoDate(value)) {
return null;
}
if (/.*T.*[+-]\d\d$/.test(value)) { // Add missing trailing zeros to timeshift
value += '00';
}
const date = new Date(value);
if (isNaN(date.getTime())) {
return null;
}
return date.toISOString();
};
internals.length = function (schema, name, limit, operator, encoding) {
Assert(!encoding || Buffer && Buffer.isEncoding(encoding), 'Invalid encoding:', encoding); // $lab:coverage:ignore$
return schema.$_addRule({ name, method: 'length', args: { limit, encoding }, operator });
};

102
node_modules/joi/lib/types/symbol.js generated vendored Normal file
View File

@ -0,0 +1,102 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Any = require('./any');
const internals = {};
internals.Map = class extends Map {
slice() {
return new internals.Map(this);
}
};
module.exports = Any.extend({
type: 'symbol',
terms: {
map: { init: new internals.Map() }
},
coerce: {
method(value, { schema, error }) {
const lookup = schema.$_terms.map.get(value);
if (lookup) {
value = lookup;
}
if (!schema._flags.only ||
typeof value === 'symbol') {
return { value };
}
return { value, errors: error('symbol.map', { map: schema.$_terms.map }) };
}
},
validate(value, { error }) {
if (typeof value !== 'symbol') {
return { value, errors: error('symbol.base') };
}
},
rules: {
map: {
method(iterable) {
if (iterable &&
!iterable[Symbol.iterator] &&
typeof iterable === 'object') {
iterable = Object.entries(iterable);
}
Assert(iterable && iterable[Symbol.iterator], 'Iterable must be an iterable or object');
const obj = this.clone();
const symbols = [];
for (const entry of iterable) {
Assert(entry && entry[Symbol.iterator], 'Entry must be an iterable');
const [key, value] = entry;
Assert(typeof key !== 'object' && typeof key !== 'function' && typeof key !== 'symbol', 'Key must not be of type object, function, or Symbol');
Assert(typeof value === 'symbol', 'Value must be a Symbol');
obj.$_terms.map.set(key, value);
symbols.push(value);
}
return obj.valid(...symbols);
}
}
},
manifest: {
build(obj, desc) {
if (desc.map) {
obj = obj.map(desc.map);
}
return obj;
}
},
messages: {
'symbol.base': '{{#label}} must be a symbol',
'symbol.map': '{{#label}} must be one of {{#map}}'
}
});

750
node_modules/joi/lib/validator.js generated vendored Normal file
View File

@ -0,0 +1,750 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const Clone = require('@hapi/hoek/lib/clone');
const Ignore = require('@hapi/hoek/lib/ignore');
const Reach = require('@hapi/hoek/lib/reach');
const Common = require('./common');
const Errors = require('./errors');
const State = require('./state');
const internals = {
result: Symbol('result')
};
exports.entry = function (value, schema, prefs) {
let settings = Common.defaults;
if (prefs) {
Assert(prefs.warnings === undefined, 'Cannot override warnings preference in synchronous validation');
Assert(prefs.artifacts === undefined, 'Cannot override artifacts preference in synchronous validation');
settings = Common.preferences(Common.defaults, prefs);
}
const result = internals.entry(value, schema, settings);
Assert(!result.mainstay.externals.length, 'Schema with external rules must use validateAsync()');
const outcome = { value: result.value };
if (result.error) {
outcome.error = result.error;
}
if (result.mainstay.warnings.length) {
outcome.warning = Errors.details(result.mainstay.warnings);
}
if (result.mainstay.debug) {
outcome.debug = result.mainstay.debug;
}
if (result.mainstay.artifacts) {
outcome.artifacts = result.mainstay.artifacts;
}
return outcome;
};
exports.entryAsync = async function (value, schema, prefs) {
let settings = Common.defaults;
if (prefs) {
settings = Common.preferences(Common.defaults, prefs);
}
const result = internals.entry(value, schema, settings);
const mainstay = result.mainstay;
if (result.error) {
if (mainstay.debug) {
result.error.debug = mainstay.debug;
}
throw result.error;
}
if (mainstay.externals.length) {
let root = result.value;
const errors = [];
for (const external of mainstay.externals) {
const path = external.state.path;
const linked = external.schema.type === 'link' ? mainstay.links.get(external.schema) : null;
let node = root;
let key;
let parent;
const ancestors = path.length ? [root] : [];
const original = path.length ? Reach(value, path) : value;
if (path.length) {
key = path[path.length - 1];
let current = root;
for (const segment of path.slice(0, -1)) {
current = current[segment];
ancestors.unshift(current);
}
parent = ancestors[0];
node = parent[key];
}
try {
const createError = (code, local) => (linked || external.schema).$_createError(code, node, local, external.state, settings);
const output = await external.method(node, {
schema: external.schema,
linked,
state: external.state,
prefs,
original,
error: createError,
errorsArray: internals.errorsArray,
warn: (code, local) => mainstay.warnings.push((linked || external.schema).$_createError(code, node, local, external.state, settings)),
message: (messages, local) => (linked || external.schema).$_createError('external', node, local, external.state, settings, { messages })
});
if (output === undefined ||
output === node) {
continue;
}
if (output instanceof Errors.Report) {
mainstay.tracer.log(external.schema, external.state, 'rule', 'external', 'error');
errors.push(output);
if (settings.abortEarly) {
break;
}
continue;
}
if (Array.isArray(output) &&
output[Common.symbols.errors]) {
mainstay.tracer.log(external.schema, external.state, 'rule', 'external', 'error');
errors.push(...output);
if (settings.abortEarly) {
break;
}
continue;
}
if (parent) {
mainstay.tracer.value(external.state, 'rule', node, output, 'external');
parent[key] = output;
}
else {
mainstay.tracer.value(external.state, 'rule', root, output, 'external');
root = output;
}
}
catch (err) {
if (settings.errors.label) {
err.message += ` (${(external.label)})`; // Change message to include path
}
throw err;
}
}
result.value = root;
if (errors.length) {
result.error = Errors.process(errors, value, settings);
if (mainstay.debug) {
result.error.debug = mainstay.debug;
}
throw result.error;
}
}
if (!settings.warnings &&
!settings.debug &&
!settings.artifacts) {
return result.value;
}
const outcome = { value: result.value };
if (mainstay.warnings.length) {
outcome.warning = Errors.details(mainstay.warnings);
}
if (mainstay.debug) {
outcome.debug = mainstay.debug;
}
if (mainstay.artifacts) {
outcome.artifacts = mainstay.artifacts;
}
return outcome;
};
internals.Mainstay = class {
constructor(tracer, debug, links) {
this.externals = [];
this.warnings = [];
this.tracer = tracer;
this.debug = debug;
this.links = links;
this.shadow = null;
this.artifacts = null;
this._snapshots = [];
}
snapshot() {
this._snapshots.push({
externals: this.externals.slice(),
warnings: this.warnings.slice()
});
}
restore() {
const snapshot = this._snapshots.pop();
this.externals = snapshot.externals;
this.warnings = snapshot.warnings;
}
commit() {
this._snapshots.pop();
}
};
internals.entry = function (value, schema, prefs) {
// Prepare state
const { tracer, cleanup } = internals.tracer(schema, prefs);
const debug = prefs.debug ? [] : null;
const links = schema._ids._schemaChain ? new Map() : null;
const mainstay = new internals.Mainstay(tracer, debug, links);
const schemas = schema._ids._schemaChain ? [{ schema }] : null;
const state = new State([], [], { mainstay, schemas });
// Validate value
const result = exports.validate(value, schema, state, prefs);
// Process value and errors
if (cleanup) {
schema.$_root.untrace();
}
const error = Errors.process(result.errors, value, prefs);
return { value: result.value, error, mainstay };
};
internals.tracer = function (schema, prefs) {
if (schema.$_root._tracer) {
return { tracer: schema.$_root._tracer._register(schema) };
}
if (prefs.debug) {
Assert(schema.$_root.trace, 'Debug mode not supported');
return { tracer: schema.$_root.trace()._register(schema), cleanup: true };
}
return { tracer: internals.ignore };
};
exports.validate = function (value, schema, state, prefs, overrides = {}) {
if (schema.$_terms.whens) {
schema = schema._generate(value, state, prefs).schema;
}
// Setup state and settings
if (schema._preferences) {
prefs = internals.prefs(schema, prefs);
}
// Cache
if (schema._cache &&
prefs.cache) {
const result = schema._cache.get(value);
state.mainstay.tracer.debug(state, 'validate', 'cached', !!result);
if (result) {
return result;
}
}
// Helpers
const createError = (code, local, localState) => schema.$_createError(code, value, local, localState || state, prefs);
const helpers = {
original: value,
prefs,
schema,
state,
error: createError,
errorsArray: internals.errorsArray,
warn: (code, local, localState) => state.mainstay.warnings.push(createError(code, local, localState)),
message: (messages, local) => schema.$_createError('custom', value, local, state, prefs, { messages })
};
// Prepare
state.mainstay.tracer.entry(schema, state);
const def = schema._definition;
if (def.prepare &&
value !== undefined &&
prefs.convert) {
const prepared = def.prepare(value, helpers);
if (prepared) {
state.mainstay.tracer.value(state, 'prepare', value, prepared.value);
if (prepared.errors) {
return internals.finalize(prepared.value, [].concat(prepared.errors), helpers); // Prepare error always aborts early
}
value = prepared.value;
}
}
// Type coercion
if (def.coerce &&
value !== undefined &&
prefs.convert &&
(!def.coerce.from || def.coerce.from.includes(typeof value))) {
const coerced = def.coerce.method(value, helpers);
if (coerced) {
state.mainstay.tracer.value(state, 'coerced', value, coerced.value);
if (coerced.errors) {
return internals.finalize(coerced.value, [].concat(coerced.errors), helpers); // Coerce error always aborts early
}
value = coerced.value;
}
}
// Empty value
const empty = schema._flags.empty;
if (empty &&
empty.$_match(internals.trim(value, schema), state.nest(empty), Common.defaults)) {
state.mainstay.tracer.value(state, 'empty', value, undefined);
value = undefined;
}
// Presence requirements (required, optional, forbidden)
const presence = overrides.presence || schema._flags.presence || (schema._flags._endedSwitch ? null : prefs.presence);
if (value === undefined) {
if (presence === 'forbidden') {
return internals.finalize(value, null, helpers);
}
if (presence === 'required') {
return internals.finalize(value, [schema.$_createError('any.required', value, null, state, prefs)], helpers);
}
if (presence === 'optional') {
if (schema._flags.default !== Common.symbols.deepDefault) {
return internals.finalize(value, null, helpers);
}
state.mainstay.tracer.value(state, 'default', value, {});
value = {};
}
}
else if (presence === 'forbidden') {
return internals.finalize(value, [schema.$_createError('any.unknown', value, null, state, prefs)], helpers);
}
// Allowed values
const errors = [];
if (schema._valids) {
const match = schema._valids.get(value, state, prefs, schema._flags.insensitive);
if (match) {
if (prefs.convert) {
state.mainstay.tracer.value(state, 'valids', value, match.value);
value = match.value;
}
state.mainstay.tracer.filter(schema, state, 'valid', match);
return internals.finalize(value, null, helpers);
}
if (schema._flags.only) {
const report = schema.$_createError('any.only', value, { valids: schema._valids.values({ display: true }) }, state, prefs);
if (prefs.abortEarly) {
return internals.finalize(value, [report], helpers);
}
errors.push(report);
}
}
// Denied values
if (schema._invalids) {
const match = schema._invalids.get(value, state, prefs, schema._flags.insensitive);
if (match) {
state.mainstay.tracer.filter(schema, state, 'invalid', match);
const report = schema.$_createError('any.invalid', value, { invalids: schema._invalids.values({ display: true }) }, state, prefs);
if (prefs.abortEarly) {
return internals.finalize(value, [report], helpers);
}
errors.push(report);
}
}
// Base type
if (def.validate) {
const base = def.validate(value, helpers);
if (base) {
state.mainstay.tracer.value(state, 'base', value, base.value);
value = base.value;
if (base.errors) {
if (!Array.isArray(base.errors)) {
errors.push(base.errors);
return internals.finalize(value, errors, helpers); // Base error always aborts early
}
if (base.errors.length) {
errors.push(...base.errors);
return internals.finalize(value, errors, helpers); // Base error always aborts early
}
}
}
}
// Validate tests
if (!schema._rules.length) {
return internals.finalize(value, errors, helpers);
}
return internals.rules(value, errors, helpers);
};
internals.rules = function (value, errors, helpers) {
const { schema, state, prefs } = helpers;
for (const rule of schema._rules) {
const definition = schema._definition.rules[rule.method];
// Skip rules that are also applied in coerce step
if (definition.convert &&
prefs.convert) {
state.mainstay.tracer.log(schema, state, 'rule', rule.name, 'full');
continue;
}
// Resolve references
let ret;
let args = rule.args;
if (rule._resolve.length) {
args = Object.assign({}, args); // Shallow copy
for (const key of rule._resolve) {
const resolver = definition.argsByName.get(key);
const resolved = args[key].resolve(value, state, prefs);
const normalized = resolver.normalize ? resolver.normalize(resolved) : resolved;
const invalid = Common.validateArg(normalized, null, resolver);
if (invalid) {
ret = schema.$_createError('any.ref', resolved, { arg: key, ref: args[key], reason: invalid }, state, prefs);
break;
}
args[key] = normalized;
}
}
// Test rule
ret = ret || definition.validate(value, helpers, args, rule); // Use ret if already set to reference error
const result = internals.rule(ret, rule);
if (result.errors) {
state.mainstay.tracer.log(schema, state, 'rule', rule.name, 'error');
if (rule.warn) {
state.mainstay.warnings.push(...result.errors);
continue;
}
if (prefs.abortEarly) {
return internals.finalize(value, result.errors, helpers);
}
errors.push(...result.errors);
}
else {
state.mainstay.tracer.log(schema, state, 'rule', rule.name, 'pass');
state.mainstay.tracer.value(state, 'rule', value, result.value, rule.name);
value = result.value;
}
}
return internals.finalize(value, errors, helpers);
};
internals.rule = function (ret, rule) {
if (ret instanceof Errors.Report) {
internals.error(ret, rule);
return { errors: [ret], value: null };
}
if (Array.isArray(ret) &&
ret[Common.symbols.errors]) {
ret.forEach((report) => internals.error(report, rule));
return { errors: ret, value: null };
}
return { errors: null, value: ret };
};
internals.error = function (report, rule) {
if (rule.message) {
report._setTemplate(rule.message);
}
return report;
};
internals.finalize = function (value, errors, helpers) {
errors = errors || [];
const { schema, state, prefs } = helpers;
// Failover value
if (errors.length) {
const failover = internals.default('failover', undefined, errors, helpers);
if (failover !== undefined) {
state.mainstay.tracer.value(state, 'failover', value, failover);
value = failover;
errors = [];
}
}
// Error override
if (errors.length &&
schema._flags.error) {
if (typeof schema._flags.error === 'function') {
errors = schema._flags.error(errors);
if (!Array.isArray(errors)) {
errors = [errors];
}
for (const error of errors) {
Assert(error instanceof Error || error instanceof Errors.Report, 'error() must return an Error object');
}
}
else {
errors = [schema._flags.error];
}
}
// Default
if (value === undefined) {
const defaulted = internals.default('default', value, errors, helpers);
state.mainstay.tracer.value(state, 'default', value, defaulted);
value = defaulted;
}
// Cast
if (schema._flags.cast &&
value !== undefined) {
const caster = schema._definition.cast[schema._flags.cast];
if (caster.from(value)) {
const casted = caster.to(value, helpers);
state.mainstay.tracer.value(state, 'cast', value, casted, schema._flags.cast);
value = casted;
}
}
// Externals
if (schema.$_terms.externals &&
prefs.externals &&
prefs._externals !== false) { // Disabled for matching
for (const { method } of schema.$_terms.externals) {
state.mainstay.externals.push({ method, schema, state, label: Errors.label(schema._flags, state, prefs) });
}
}
// Result
const result = { value, errors: errors.length ? errors : null };
if (schema._flags.result) {
result.value = schema._flags.result === 'strip' ? undefined : /* raw */ helpers.original;
state.mainstay.tracer.value(state, schema._flags.result, value, result.value);
state.shadow(value, schema._flags.result);
}
// Cache
if (schema._cache &&
prefs.cache !== false &&
!schema._refs.length) {
schema._cache.set(helpers.original, result);
}
// Artifacts
if (value !== undefined &&
!result.errors &&
schema._flags.artifact !== undefined) {
state.mainstay.artifacts = state.mainstay.artifacts || new Map();
if (!state.mainstay.artifacts.has(schema._flags.artifact)) {
state.mainstay.artifacts.set(schema._flags.artifact, []);
}
state.mainstay.artifacts.get(schema._flags.artifact).push(state.path);
}
return result;
};
internals.prefs = function (schema, prefs) {
const isDefaultOptions = prefs === Common.defaults;
if (isDefaultOptions &&
schema._preferences[Common.symbols.prefs]) {
return schema._preferences[Common.symbols.prefs];
}
prefs = Common.preferences(prefs, schema._preferences);
if (isDefaultOptions) {
schema._preferences[Common.symbols.prefs] = prefs;
}
return prefs;
};
internals.default = function (flag, value, errors, helpers) {
const { schema, state, prefs } = helpers;
const source = schema._flags[flag];
if (prefs.noDefaults ||
source === undefined) {
return value;
}
state.mainstay.tracer.log(schema, state, 'rule', flag, 'full');
if (!source) {
return source;
}
if (typeof source === 'function') {
const args = source.length ? [Clone(state.ancestors[0]), helpers] : [];
try {
return source(...args);
}
catch (err) {
errors.push(schema.$_createError(`any.${flag}`, null, { error: err }, state, prefs));
return;
}
}
if (typeof source !== 'object') {
return source;
}
if (source[Common.symbols.literal]) {
return source.literal;
}
if (Common.isResolvable(source)) {
return source.resolve(value, state, prefs);
}
return Clone(source);
};
internals.trim = function (value, schema) {
if (typeof value !== 'string') {
return value;
}
const trim = schema.$_getRule('trim');
if (!trim ||
!trim.args.enabled) {
return value;
}
return value.trim();
};
internals.ignore = {
active: false,
debug: Ignore,
entry: Ignore,
filter: Ignore,
log: Ignore,
resolve: Ignore,
value: Ignore
};
internals.errorsArray = function () {
const errors = [];
errors[Common.symbols.errors] = true;
return errors;
};

263
node_modules/joi/lib/values.js generated vendored Normal file
View File

@ -0,0 +1,263 @@
'use strict';
const Assert = require('@hapi/hoek/lib/assert');
const DeepEqual = require('@hapi/hoek/lib/deepEqual');
const Common = require('./common');
const internals = {};
module.exports = internals.Values = class {
constructor(values, refs) {
this._values = new Set(values);
this._refs = new Set(refs);
this._lowercase = internals.lowercases(values);
this._override = false;
}
get length() {
return this._values.size + this._refs.size;
}
add(value, refs) {
// Reference
if (Common.isResolvable(value)) {
if (!this._refs.has(value)) {
this._refs.add(value);
if (refs) { // Skipped in a merge
refs.register(value);
}
}
return;
}
// Value
if (!this.has(value, null, null, false)) {
this._values.add(value);
if (typeof value === 'string') {
this._lowercase.set(value.toLowerCase(), value);
}
}
}
static merge(target, source, remove) {
target = target || new internals.Values();
if (source) {
if (source._override) {
return source.clone();
}
for (const item of [...source._values, ...source._refs]) {
target.add(item);
}
}
if (remove) {
for (const item of [...remove._values, ...remove._refs]) {
target.remove(item);
}
}
return target.length ? target : null;
}
remove(value) {
// Reference
if (Common.isResolvable(value)) {
this._refs.delete(value);
return;
}
// Value
this._values.delete(value);
if (typeof value === 'string') {
this._lowercase.delete(value.toLowerCase());
}
}
has(value, state, prefs, insensitive) {
return !!this.get(value, state, prefs, insensitive);
}
get(value, state, prefs, insensitive) {
if (!this.length) {
return false;
}
// Simple match
if (this._values.has(value)) {
return { value };
}
// Case insensitive string match
if (typeof value === 'string' &&
value &&
insensitive) {
const found = this._lowercase.get(value.toLowerCase());
if (found) {
return { value: found };
}
}
if (!this._refs.size &&
typeof value !== 'object') {
return false;
}
// Objects
if (typeof value === 'object') {
for (const item of this._values) {
if (DeepEqual(item, value)) {
return { value: item };
}
}
}
// References
if (state) {
for (const ref of this._refs) {
const resolved = ref.resolve(value, state, prefs, null, { in: true });
if (resolved === undefined) {
continue;
}
const items = !ref.in || typeof resolved !== 'object'
? [resolved]
: Array.isArray(resolved) ? resolved : Object.keys(resolved);
for (const item of items) {
if (typeof item !== typeof value) {
continue;
}
if (insensitive &&
value &&
typeof value === 'string') {
if (item.toLowerCase() === value.toLowerCase()) {
return { value: item, ref };
}
}
else {
if (DeepEqual(item, value)) {
return { value: item, ref };
}
}
}
}
}
return false;
}
override() {
this._override = true;
}
values(options) {
if (options &&
options.display) {
const values = [];
for (const item of [...this._values, ...this._refs]) {
if (item !== undefined) {
values.push(item);
}
}
return values;
}
return Array.from([...this._values, ...this._refs]);
}
clone() {
const set = new internals.Values(this._values, this._refs);
set._override = this._override;
return set;
}
concat(source) {
Assert(!source._override, 'Cannot concat override set of values');
const set = new internals.Values([...this._values, ...source._values], [...this._refs, ...source._refs]);
set._override = this._override;
return set;
}
describe() {
const normalized = [];
if (this._override) {
normalized.push({ override: true });
}
for (const value of this._values.values()) {
normalized.push(value && typeof value === 'object' ? { value } : value);
}
for (const value of this._refs.values()) {
normalized.push(value.describe());
}
return normalized;
}
};
internals.Values.prototype[Common.symbols.values] = true;
// Aliases
internals.Values.prototype.slice = internals.Values.prototype.clone;
// Helpers
internals.lowercases = function (from) {
const map = new Map();
if (from) {
for (const value of from) {
if (typeof value === 'string') {
map.set(value.toLowerCase(), value);
}
}
}
return map;
};

70
node_modules/joi/package.json generated vendored Normal file
View File

@ -0,0 +1,70 @@
{
"_from": "joi@^17.4.0",
"_id": "joi@17.9.2",
"_inBundle": false,
"_integrity": "sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw==",
"_location": "/joi",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "joi@^17.4.0",
"name": "joi",
"escapedName": "joi",
"rawSpec": "^17.4.0",
"saveSpec": null,
"fetchSpec": "^17.4.0"
},
"_requiredBy": [
"/@vue/cli-shared-utils"
],
"_resolved": "https://registry.npmjs.org/joi/-/joi-17.9.2.tgz",
"_shasum": "8b2e4724188369f55451aebd1d0b1d9482470690",
"_spec": "joi@^17.4.0",
"_where": "C:\\Users\\zhouxueli\\Desktop\\scheduling-app\\node_modules\\@vue\\cli-shared-utils",
"browser": "dist/joi-browser.min.js",
"bugs": {
"url": "https://github.com/hapijs/joi/issues"
},
"bundleDependencies": false,
"dependencies": {
"@hapi/hoek": "^9.0.0",
"@hapi/topo": "^5.0.0",
"@sideway/address": "^4.1.3",
"@sideway/formula": "^3.0.1",
"@sideway/pinpoint": "^2.0.0"
},
"deprecated": false,
"description": "Object schema validation",
"devDependencies": {
"@hapi/bourne": "2.x.x",
"@hapi/code": "8.x.x",
"@hapi/joi-legacy-test": "npm:@hapi/joi@15.x.x",
"@hapi/lab": "^25.0.1",
"@types/node": "^14.18.24",
"typescript": "4.3.x"
},
"files": [
"lib/**/*",
"dist/*"
],
"homepage": "https://github.com/hapijs/joi#readme",
"keywords": [
"schema",
"validation"
],
"license": "BSD-3-Clause",
"main": "lib/index.js",
"name": "joi",
"repository": {
"type": "git",
"url": "git://github.com/hapijs/joi.git"
},
"scripts": {
"prepublishOnly": "cd browser && npm install && npm run build",
"test": "lab -t 100 -a @hapi/code -L -Y",
"test-cov-html": "lab -r html -o coverage.html -a @hapi/code"
},
"types": "lib/index.d.ts",
"version": "17.9.2"
}