You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
4.8 KiB
217 lines
4.8 KiB
'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);
|
|
}
|
|
};
|