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.
216 lines
4.8 KiB
216 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); |
|
} |
|
};
|
|
|