167 lines
3.8 KiB
JavaScript
167 lines
3.8 KiB
JavaScript
'use strict';
|
|
|
|
const Assert = require('@hapi/hoek/assert');
|
|
const Clone = require('@hapi/hoek/clone');
|
|
|
|
const Common = require('./common');
|
|
const Compile = require('./compile');
|
|
const Errors = require('./errors');
|
|
const Ref = require('./ref');
|
|
|
|
|
|
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];
|
|
}
|
|
|
|
return root;
|
|
};
|
|
|
|
|
|
internals.methods = {
|
|
|
|
ValidationError: Errors.ValidationError,
|
|
version: Common.version,
|
|
|
|
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);
|
|
},
|
|
|
|
checkPreferences(prefs) {
|
|
|
|
Common.checkPreferences(prefs);
|
|
},
|
|
|
|
compile(schema, options) {
|
|
|
|
return Compile.compile(this, schema, options);
|
|
},
|
|
|
|
isError: Errors.ValidationError.isError,
|
|
isRef: Ref.isRef,
|
|
isSchema: Common.isSchema,
|
|
|
|
in(...args) {
|
|
|
|
return Ref.in(...args);
|
|
},
|
|
|
|
override: Common.symbols.override,
|
|
|
|
ref(...args) {
|
|
|
|
return Ref.create(...args);
|
|
}
|
|
};
|
|
|
|
|
|
// 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 ? 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);
|
|
};
|
|
|
|
|
|
module.exports = internals.root();
|