'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); } };