joi
Version:
Object schema validation
1 lines • 550 kB
Source Map (JSON)
{"version":3,"file":"joi-browser.min.mjs","names":["NON_ASCII_RX","Url","Util"],"sources":["../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/assertError.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/stringify.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/assert.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/reach.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/types.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/utils.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/clone.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/merge.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/applyToDefaults.js","../browser/stubs/empty.cjs","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/deepEqual.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/escapeHtml.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/escapeRegex.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/ignore.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/index.js","../lib/schemas.js","../node_modules/.pnpm/@hapi+formula@3.0.2/node_modules/@hapi/formula/lib/index.js","../lib/errors.js","../lib/ref.js","../lib/template.js","../lib/messages.js","../lib/common.js","../lib/cache.js","../lib/compile.js","../lib/extend.js","../lib/modify.js","../lib/state.js","../lib/validator.js","../lib/values.js","../lib/base.js","../lib/types/any.js","../lib/types/alternatives.js","../lib/types/array.js","../lib/types/boolean.js","../lib/types/date.js","../node_modules/.pnpm/@hapi+topo@6.0.2/node_modules/@hapi/topo/lib/index.js","../lib/types/keys.js","../lib/types/function.js","../lib/types/link.js","../lib/types/number.js","../lib/types/object.js","../node_modules/.pnpm/@hapi+address@5.1.1/node_modules/@hapi/address/esm/errors.js","../node_modules/.pnpm/@hapi+address@5.1.1/node_modules/@hapi/address/esm/domain.js","../node_modules/.pnpm/@hapi+address@5.1.1/node_modules/@hapi/address/esm/email.js","../node_modules/.pnpm/@hapi+hoek@11.0.7/node_modules/@hapi/hoek/lib/index.mjs","../node_modules/.pnpm/@hapi+address@5.1.1/node_modules/@hapi/address/esm/uri.js","../node_modules/.pnpm/@hapi+address@5.1.1/node_modules/@hapi/address/esm/ip.js","../node_modules/.pnpm/@hapi+address@5.1.1/node_modules/@hapi/address/esm/index.js","../lib/types/string.js","../lib/types/symbol.js","../lib/index.js"],"sourcesContent":["'use strict';\n\nconst internals = {};\n\n\nmodule.exports = class AssertError extends Error {\n\n name = 'AssertError';\n\n constructor(message, ctor) {\n\n super(message || 'Unknown error');\n\n if (typeof Error.captureStackTrace === 'function') { // $lab:coverage:ignore$\n Error.captureStackTrace(this, ctor);\n }\n }\n};\n","'use strict';\n\nconst internals = {};\n\n\nmodule.exports = function (...args) {\n\n try {\n return JSON.stringify(...args);\n }\n catch (err) {\n return '[Cannot display object: ' + err.message + ']';\n }\n};\n","'use strict';\n\nconst AssertError = require('./assertError');\nconst Stringify = require('./stringify');\n\n\nconst internals = {};\n\n\nconst assert = module.exports = function (condition, ...args) {\n\n if (condition) {\n return;\n }\n\n if (args.length === 1 &&\n args[0] instanceof Error) {\n\n throw args[0];\n }\n\n const msgs = args\n .filter((arg) => arg !== '')\n .map((arg) => {\n\n return typeof arg === 'string' ? arg : arg instanceof Error ? arg.message : Stringify(arg);\n });\n\n throw new AssertError(msgs.join(' '), assert);\n};\n","'use strict';\n\nconst Assert = require('./assert');\n\n\nconst internals = {};\n\n\nmodule.exports = function (obj, chain, options) {\n\n if (chain === false ||\n chain === null ||\n chain === undefined) {\n\n return obj;\n }\n\n options = options || {};\n if (typeof options === 'string') {\n options = { separator: options };\n }\n\n const isChainArray = Array.isArray(chain);\n\n Assert(!isChainArray || !options.separator, 'Separator option is not valid for array-based chain');\n\n const path = isChainArray ? chain : chain.split(options.separator || '.');\n let ref = obj;\n for (let i = 0; i < path.length; ++i) {\n let key = path[i];\n const type = options.iterables && internals.iterables(ref);\n\n if (Array.isArray(ref) ||\n type === 'set') {\n\n const number = Number(key);\n if (Number.isInteger(number)) {\n key = number < 0 ? ref.length + number : number;\n }\n }\n\n if (!ref ||\n typeof ref === 'function' && options.functions === false || // Defaults to true\n !type && ref[key] === undefined) {\n\n Assert(!options.strict || i + 1 === path.length, 'Missing segment', key, 'in reach path ', chain);\n Assert(typeof ref === 'object' || options.functions === true || typeof ref !== 'function', 'Invalid segment', key, 'in reach path ', chain);\n ref = options.default;\n break;\n }\n\n if (!type) {\n ref = ref[key];\n }\n else if (type === 'set') {\n ref = [...ref][key];\n }\n else { // type === 'map'\n ref = ref.get(key);\n }\n }\n\n return ref;\n};\n\n\ninternals.iterables = function (ref) {\n\n if (ref instanceof Set) {\n return 'set';\n }\n\n if (ref instanceof Map) {\n return 'map';\n }\n};\n","'use strict';\n\nconst internals = {};\n\n\nexports = module.exports = {\n array: Array.prototype,\n buffer: Buffer && Buffer.prototype, // $lab:coverage:ignore$\n date: Date.prototype,\n error: Error.prototype,\n generic: Object.prototype,\n map: Map.prototype,\n promise: Promise.prototype,\n regex: RegExp.prototype,\n set: Set.prototype,\n url: URL.prototype,\n weakMap: WeakMap.prototype,\n weakSet: WeakSet.prototype\n};\n\n\ninternals.typeMap = new Map([\n ['[object Error]', exports.error],\n ['[object Map]', exports.map],\n ['[object Promise]', exports.promise],\n ['[object Set]', exports.set],\n ['[object URL]', exports.url],\n ['[object WeakMap]', exports.weakMap],\n ['[object WeakSet]', exports.weakSet]\n]);\n\n\nexports.getInternalProto = function (obj) {\n\n if (Array.isArray(obj)) {\n return exports.array;\n }\n\n if (Buffer && obj instanceof Buffer) { // $lab:coverage:ignore$\n return exports.buffer;\n }\n\n if (obj instanceof Date) {\n return exports.date;\n }\n\n if (obj instanceof RegExp) {\n return exports.regex;\n }\n\n if (obj instanceof Error) {\n return exports.error;\n }\n\n const objName = Object.prototype.toString.call(obj);\n return internals.typeMap.get(objName) || exports.generic;\n};\n","'use strict';\n\nconst internals = {};\n\n\nexports.keys = function (obj, options = {}) {\n\n return options.symbols !== false ? Reflect.ownKeys(obj) : Object.getOwnPropertyNames(obj); // Defaults to true\n};\n","'use strict';\n\nconst Reach = require('./reach');\nconst Types = require('./types');\nconst Utils = require('./utils');\n\n\nconst internals = {\n needsProtoHack: new Set([Types.set, Types.map, Types.weakSet, Types.weakMap]),\n structuredCloneExists: typeof structuredClone === 'function'\n};\n\n\nmodule.exports = internals.clone = function (obj, options = {}, _seen = null) {\n\n if (typeof obj !== 'object' ||\n obj === null) {\n\n return obj;\n }\n\n let clone = internals.clone;\n let seen = _seen;\n\n if (options.shallow) {\n if (options.shallow !== true) {\n return internals.cloneWithShallow(obj, options);\n }\n\n clone = (value) => value;\n }\n else if (seen) {\n const lookup = seen.get(obj);\n if (lookup) {\n return lookup;\n }\n }\n else {\n seen = new Map();\n }\n\n // Built-in object types\n\n const baseProto = Types.getInternalProto(obj);\n switch (baseProto) {\n case Types.buffer:\n return Buffer?.from(obj);\n case Types.date:\n return new Date(obj.getTime());\n case Types.regex:\n case Types.url:\n return new baseProto.constructor(obj);\n }\n\n // Generic objects\n\n const newObj = internals.base(obj, baseProto, options);\n if (newObj === obj) {\n return obj;\n }\n\n if (seen) {\n seen.set(obj, newObj); // Set seen, since obj could recurse\n }\n\n if (baseProto === Types.set) {\n for (const value of obj) {\n newObj.add(clone(value, options, seen));\n }\n }\n else if (baseProto === Types.map) {\n for (const [key, value] of obj) {\n newObj.set(key, clone(value, options, seen));\n }\n }\n\n const keys = Utils.keys(obj, options);\n for (const key of keys) {\n if (key === '__proto__') {\n continue;\n }\n\n if (baseProto === Types.array &&\n key === 'length') {\n\n newObj.length = obj.length;\n continue;\n }\n\n // Can only be covered in node 21+\n /* $lab:coverage:off$ */\n if (internals.structuredCloneExists &&\n baseProto === Types.error &&\n key === 'stack') {\n\n continue; // Already a part of the base object\n }\n /* $lab:coverage:on$ */\n\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n if (descriptor) {\n if (descriptor.get ||\n descriptor.set) {\n\n Object.defineProperty(newObj, key, descriptor);\n }\n else if (descriptor.enumerable) {\n newObj[key] = clone(obj[key], options, seen);\n }\n else {\n Object.defineProperty(newObj, key, { enumerable: false, writable: true, configurable: true, value: clone(obj[key], options, seen) });\n }\n }\n else {\n Object.defineProperty(newObj, key, {\n enumerable: true,\n writable: true,\n configurable: true,\n value: clone(obj[key], options, seen)\n });\n }\n }\n\n return newObj;\n};\n\n\ninternals.cloneWithShallow = function (source, options) {\n\n const keys = options.shallow;\n options = Object.assign({}, options);\n options.shallow = false;\n\n const seen = new Map();\n\n for (const key of keys) {\n const ref = Reach(source, key);\n if (typeof ref === 'object' ||\n typeof ref === 'function') {\n\n seen.set(ref, ref);\n }\n }\n\n return internals.clone(source, options, seen);\n};\n\n\ninternals.base = function (obj, baseProto, options) {\n\n if (options.prototype === false) { // Defaults to true\n if (internals.needsProtoHack.has(baseProto)) {\n return new baseProto.constructor();\n }\n\n return baseProto === Types.array ? [] : {};\n }\n\n const proto = Object.getPrototypeOf(obj);\n if (proto &&\n proto.isImmutable) {\n\n return obj;\n }\n\n if (baseProto === Types.array) {\n const newObj = [];\n if (proto !== baseProto) {\n Object.setPrototypeOf(newObj, proto);\n }\n\n return newObj;\n }\n // Can only be covered in node 21+\n /* $lab:coverage:off$ */\n else if (baseProto === Types.error && internals.structuredCloneExists &&\n (proto === baseProto || Error.isPrototypeOf(proto.constructor))) { // Don't match Util.inherit() subclassed errors\n\n const err = structuredClone(obj); // Needed to copy internal stack state\n if (Object.getPrototypeOf(err) !== proto) {\n Object.setPrototypeOf(err, proto); // Fix prototype\n }\n\n return err;\n }\n /* $lab:coverage:on$ */\n\n if (internals.needsProtoHack.has(baseProto)) {\n const newObj = new proto.constructor();\n if (proto !== baseProto) {\n Object.setPrototypeOf(newObj, proto);\n }\n\n return newObj;\n }\n\n return Object.create(proto);\n};\n","'use strict';\n\nconst Assert = require('./assert');\nconst Clone = require('./clone');\nconst Utils = require('./utils');\n\n\nconst internals = {};\n\n\nmodule.exports = internals.merge = function (target, source, options) {\n\n Assert(target && typeof target === 'object', 'Invalid target value: must be an object');\n Assert(source === null || source === undefined || typeof source === 'object', 'Invalid source value: must be null, undefined, or an object');\n\n if (!source) {\n return target;\n }\n\n options = Object.assign({ nullOverride: true, mergeArrays: true }, options);\n\n if (Array.isArray(source)) {\n Assert(Array.isArray(target), 'Cannot merge array onto an object');\n if (!options.mergeArrays) {\n target.length = 0; // Must not change target assignment\n }\n\n for (let i = 0; i < source.length; ++i) {\n target.push(Clone(source[i], { symbols: options.symbols }));\n }\n\n return target;\n }\n\n const keys = Utils.keys(source, options);\n for (let i = 0; i < keys.length; ++i) {\n const key = keys[i];\n if (key === '__proto__' ||\n !Object.prototype.propertyIsEnumerable.call(source, key)) {\n\n continue;\n }\n\n const value = source[key];\n if (value &&\n typeof value === 'object') {\n\n if (target[key] === value) {\n continue; // Can occur for shallow merges\n }\n\n if (!target[key] ||\n typeof target[key] !== 'object' ||\n (Array.isArray(target[key]) !== Array.isArray(value)) ||\n value instanceof Date ||\n (Buffer && Buffer.isBuffer(value)) || // $lab:coverage:ignore$\n value instanceof RegExp) {\n\n target[key] = Clone(value, { symbols: options.symbols });\n }\n else {\n internals.merge(target[key], value, options);\n }\n }\n else {\n if (value !== null &&\n value !== undefined) { // Explicit to preserve empty strings\n\n target[key] = value;\n }\n else if (options.nullOverride) {\n target[key] = value;\n }\n }\n }\n\n return target;\n};\n","'use strict';\n\nconst Assert = require('./assert');\nconst Clone = require('./clone');\nconst Merge = require('./merge');\nconst Reach = require('./reach');\n\n\nconst internals = {};\n\n\nmodule.exports = function (defaults, source, options = {}) {\n\n Assert(defaults && typeof defaults === 'object', 'Invalid defaults value: must be an object');\n Assert(!source || source === true || typeof source === 'object', 'Invalid source value: must be true, falsy or an object');\n Assert(typeof options === 'object', 'Invalid options: must be an object');\n\n if (!source) { // If no source, return null\n return null;\n }\n\n if (options.shallow) {\n return internals.applyToDefaultsWithShallow(defaults, source, options);\n }\n\n const copy = Clone(defaults);\n\n if (source === true) { // If source is set to true, use defaults\n return copy;\n }\n\n const nullOverride = options.nullOverride !== undefined ? options.nullOverride : false;\n return Merge(copy, source, { nullOverride, mergeArrays: false });\n};\n\n\ninternals.applyToDefaultsWithShallow = function (defaults, source, options) {\n\n const keys = options.shallow;\n Assert(Array.isArray(keys), 'Invalid keys');\n\n const seen = new Map();\n const merge = source === true ? null : new Set();\n\n for (let key of keys) {\n key = Array.isArray(key) ? key : key.split('.'); // Pre-split optimization\n\n const ref = Reach(defaults, key);\n if (ref &&\n typeof ref === 'object') {\n\n seen.set(ref, merge && Reach(source, key) || ref);\n }\n else if (merge) {\n merge.add(key);\n }\n }\n\n const copy = Clone(defaults, {}, seen);\n\n if (!merge) {\n return copy;\n }\n\n for (const key of merge) {\n internals.reachCopy(copy, source, key);\n }\n\n const nullOverride = options.nullOverride !== undefined ? options.nullOverride : false;\n return Merge(copy, source, { nullOverride, mergeArrays: false });\n};\n\n\ninternals.reachCopy = function (dst, src, path) {\n\n for (const segment of path) {\n if (!(segment in src)) {\n return;\n }\n\n const val = src[segment];\n\n if (typeof val !== 'object' || val === null) {\n return;\n }\n\n src = val;\n }\n\n const value = src;\n let ref = dst;\n for (let i = 0; i < path.length - 1; ++i) {\n const segment = path[i];\n if (typeof ref[segment] !== 'object') {\n ref[segment] = {};\n }\n\n ref = ref[segment];\n }\n\n ref[path[path.length - 1]] = value;\n};\n","module.exports = {};\n","'use strict';\n\nconst Types = require('./types');\n\n\nconst internals = {\n mismatched: null\n};\n\n\nmodule.exports = function (obj, ref, options) {\n\n options = Object.assign({ prototype: true }, options);\n\n return !!internals.isDeepEqual(obj, ref, options, []);\n};\n\n\ninternals.isDeepEqual = function (obj, ref, options, seen) {\n\n if (obj === ref) { // Copied from Deep-eql, copyright(c) 2013 Jake Luer, jake@alogicalparadox.com, MIT Licensed, https://github.com/chaijs/deep-eql\n return obj !== 0 || 1 / obj === 1 / ref;\n }\n\n const type = typeof obj;\n\n if (type !== typeof ref) {\n return false;\n }\n\n if (obj === null ||\n ref === null) {\n\n return false;\n }\n\n if (type === 'function') {\n if (!options.deepFunction ||\n obj.toString() !== ref.toString()) {\n\n return false;\n }\n\n // Continue as object\n }\n else if (type !== 'object') {\n return obj !== obj && ref !== ref; // NaN\n }\n\n const instanceType = internals.getSharedType(obj, ref, !!options.prototype);\n switch (instanceType) {\n case Types.buffer:\n return Buffer && Buffer.prototype.equals.call(obj, ref); // $lab:coverage:ignore$\n case Types.promise:\n return obj === ref;\n case Types.regex:\n case Types.url:\n return obj.toString() === ref.toString();\n case internals.mismatched:\n return false;\n }\n\n for (let i = seen.length - 1; i >= 0; --i) {\n if (seen[i].isSame(obj, ref)) {\n return true; // If previous comparison failed, it would have stopped execution\n }\n }\n\n seen.push(new internals.SeenEntry(obj, ref));\n\n try {\n return !!internals.isDeepEqualObj(instanceType, obj, ref, options, seen);\n }\n finally {\n seen.pop();\n }\n};\n\n\ninternals.getSharedType = function (obj, ref, checkPrototype) {\n\n if (checkPrototype) {\n if (Object.getPrototypeOf(obj) !== Object.getPrototypeOf(ref)) {\n return internals.mismatched;\n }\n\n return Types.getInternalProto(obj);\n }\n\n const type = Types.getInternalProto(obj);\n if (type !== Types.getInternalProto(ref)) {\n return internals.mismatched;\n }\n\n return type;\n};\n\n\ninternals.valueOf = function (obj) {\n\n const objValueOf = obj.valueOf;\n if (objValueOf === undefined) {\n return obj;\n }\n\n try {\n return objValueOf.call(obj);\n }\n catch (err) {\n return err;\n }\n};\n\n\ninternals.hasOwnEnumerableProperty = function (obj, key) {\n\n return Object.prototype.propertyIsEnumerable.call(obj, key);\n};\n\n\ninternals.isSetSimpleEqual = function (obj, ref) {\n\n for (const entry of Set.prototype.values.call(obj)) {\n if (!Set.prototype.has.call(ref, entry)) {\n return false;\n }\n }\n\n return true;\n};\n\n\ninternals.isDeepEqualObj = function (instanceType, obj, ref, options, seen) {\n\n const { isDeepEqual, valueOf, hasOwnEnumerableProperty } = internals;\n const { keys, getOwnPropertySymbols } = Object;\n\n if (instanceType === Types.array) {\n if (options.part) {\n\n // Check if any index match any other index\n\n for (const objValue of obj) {\n for (const refValue of ref) {\n if (isDeepEqual(objValue, refValue, options, seen)) {\n return true;\n }\n }\n }\n }\n else {\n if (obj.length !== ref.length) {\n return false;\n }\n\n for (let i = 0; i < obj.length; ++i) {\n if (!isDeepEqual(obj[i], ref[i], options, seen)) {\n return false;\n }\n }\n\n return true;\n }\n }\n else if (instanceType === Types.set) {\n if (obj.size !== ref.size) {\n return false;\n }\n\n if (!internals.isSetSimpleEqual(obj, ref)) {\n\n // Check for deep equality\n\n const ref2 = new Set(Set.prototype.values.call(ref));\n for (const objEntry of Set.prototype.values.call(obj)) {\n if (ref2.delete(objEntry)) {\n continue;\n }\n\n let found = false;\n for (const refEntry of ref2) {\n if (isDeepEqual(objEntry, refEntry, options, seen)) {\n ref2.delete(refEntry);\n found = true;\n break;\n }\n }\n\n if (!found) {\n return false;\n }\n }\n }\n }\n else if (instanceType === Types.map) {\n if (obj.size !== ref.size) {\n return false;\n }\n\n for (const [key, value] of Map.prototype.entries.call(obj)) {\n if (value === undefined && !Map.prototype.has.call(ref, key)) {\n return false;\n }\n\n if (!isDeepEqual(value, Map.prototype.get.call(ref, key), options, seen)) {\n return false;\n }\n }\n }\n else if (instanceType === Types.error) {\n\n // Always check name and message\n\n if (obj.name !== ref.name ||\n obj.message !== ref.message) {\n\n return false;\n }\n }\n\n // Check .valueOf()\n\n const valueOfObj = valueOf(obj);\n const valueOfRef = valueOf(ref);\n if ((obj !== valueOfObj || ref !== valueOfRef) &&\n !isDeepEqual(valueOfObj, valueOfRef, options, seen)) {\n\n return false;\n }\n\n // Check properties\n\n const objKeys = keys(obj);\n if (!options.part &&\n objKeys.length !== keys(ref).length &&\n !options.skip) {\n\n return false;\n }\n\n let skipped = 0;\n for (const key of objKeys) {\n if (options.skip &&\n options.skip.includes(key)) {\n\n if (ref[key] === undefined) {\n ++skipped;\n }\n\n continue;\n }\n\n if (!hasOwnEnumerableProperty(ref, key)) {\n return false;\n }\n\n if (!isDeepEqual(obj[key], ref[key], options, seen)) {\n return false;\n }\n }\n\n if (!options.part &&\n objKeys.length - skipped !== keys(ref).length) {\n\n return false;\n }\n\n // Check symbols\n\n if (options.symbols !== false) { // Defaults to true\n const objSymbols = getOwnPropertySymbols(obj);\n const refSymbols = new Set(getOwnPropertySymbols(ref));\n\n for (const key of objSymbols) {\n if (!options.skip?.includes(key)) {\n\n if (hasOwnEnumerableProperty(obj, key)) {\n if (!hasOwnEnumerableProperty(ref, key)) {\n return false;\n }\n\n if (!isDeepEqual(obj[key], ref[key], options, seen)) {\n return false;\n }\n }\n else if (hasOwnEnumerableProperty(ref, key)) {\n return false;\n }\n }\n\n refSymbols.delete(key);\n }\n\n for (const key of refSymbols) {\n if (hasOwnEnumerableProperty(ref, key)) {\n return false;\n }\n }\n }\n\n return true;\n};\n\n\ninternals.SeenEntry = class {\n\n constructor(obj, ref) {\n\n this.obj = obj;\n this.ref = ref;\n }\n\n isSame(obj, ref) {\n\n return this.obj === obj && this.ref === ref;\n }\n};\n","'use strict';\n\nconst internals = {};\n\n\nmodule.exports = function (input) {\n\n if (!input) {\n return '';\n }\n\n let escaped = '';\n\n for (let i = 0; i < input.length; ++i) {\n\n const charCode = input.charCodeAt(i);\n\n if (internals.isSafe(charCode)) {\n escaped += input[i];\n }\n else {\n escaped += internals.escapeHtmlChar(charCode);\n }\n }\n\n return escaped;\n};\n\n\ninternals.escapeHtmlChar = function (charCode) {\n\n const namedEscape = internals.namedHtml.get(charCode);\n if (namedEscape) {\n return namedEscape;\n }\n\n if (charCode >= 256) {\n return '&#' + charCode + ';';\n }\n\n const hexValue = charCode.toString(16).padStart(2, '0');\n return `&#x${hexValue};`;\n};\n\n\ninternals.isSafe = function (charCode) {\n\n return internals.safeCharCodes.has(charCode);\n};\n\n\ninternals.namedHtml = new Map([\n [38, '&'],\n [60, '<'],\n [62, '>'],\n [34, '"'],\n [160, ' '],\n [162, '¢'],\n [163, '£'],\n [164, '¤'],\n [169, '©'],\n [174, '®']\n]);\n\n\ninternals.safeCharCodes = (function () {\n\n const safe = new Set();\n\n for (let i = 32; i < 123; ++i) {\n\n if ((i >= 97) || // a-z\n (i >= 65 && i <= 90) || // A-Z\n (i >= 48 && i <= 57) || // 0-9\n i === 32 || // space\n i === 46 || // .\n i === 44 || // ,\n i === 45 || // -\n i === 58 || // :\n i === 95) { // _\n\n safe.add(i);\n }\n }\n\n return safe;\n}());\n","'use strict';\n\nconst internals = {};\n\n\nmodule.exports = function (string) {\n\n // Escape ^$.*+-?=!:|\\/()[]{},\n\n return string.replace(/[\\^\\$\\.\\*\\+\\-\\?\\=\\!\\:\\|\\\\\\/\\(\\)\\[\\]\\{\\}\\,]/g, '\\\\$&');\n};\n","'use strict';\n\nconst internals = {};\n\n\nmodule.exports = function () { };\n","'use strict';\n\nexports.applyToDefaults = require('./applyToDefaults');\n\nexports.assert = require('./assert');\n\nexports.AssertError = require('./assertError');\n\nexports.Bench = require('./bench');\n\nexports.block = require('./block');\n\nexports.clone = require('./clone');\n\nexports.contain = require('./contain');\n\nexports.deepEqual = require('./deepEqual');\n\nexports.escapeHeaderAttribute = require('./escapeHeaderAttribute');\n\nexports.escapeHtml = require('./escapeHtml');\n\nexports.escapeJson = require('./escapeJson');\n\nexports.escapeRegex = require('./escapeRegex');\n\nexports.flatten = require('./flatten');\n\nexports.ignore = require('./ignore');\n\nexports.intersect = require('./intersect');\n\nexports.isPromise = require('./isPromise');\n\nexports.merge = require('./merge');\n\nexports.once = require('./once');\n\nexports.reach = require('./reach');\n\nexports.reachTemplate = require('./reachTemplate');\n\nexports.stringify = require('./stringify');\n\nexports.wait = require('./wait');\n","'use strict';\n\nconst Joi = require('./index');\n\n\nconst internals = {};\n\n\n// Preferences\n\ninternals.wrap = Joi.string()\n .min(1)\n .max(2)\n .allow(false);\n\n\nexports.preferences = Joi.object({\n allowUnknown: Joi.boolean(),\n abortEarly: Joi.boolean(),\n artifacts: Joi.boolean(),\n cache: Joi.boolean(),\n context: Joi.object(),\n convert: Joi.boolean(),\n dateFormat: Joi.valid('date', 'iso', 'string', 'time', 'utc'),\n debug: Joi.boolean(),\n errors: {\n escapeHtml: Joi.boolean(),\n label: Joi.valid('path', 'key', false),\n language: [\n Joi.string(),\n Joi.object().ref()\n ],\n render: Joi.boolean(),\n stack: Joi.boolean(),\n wrap: {\n label: internals.wrap,\n array: internals.wrap,\n string: internals.wrap\n }\n },\n externals: Joi.boolean(),\n messages: Joi.object(),\n noDefaults: Joi.boolean(),\n nonEnumerables: Joi.boolean(),\n presence: Joi.valid('required', 'optional', 'forbidden'),\n skipFunctions: Joi.boolean(),\n stripUnknown: Joi.object({\n arrays: Joi.boolean(),\n objects: Joi.boolean()\n })\n .or('arrays', 'objects')\n .allow(true, false),\n warnings: Joi.boolean()\n})\n .strict();\n\n\n// Extensions\n\ninternals.nameRx = /^[a-zA-Z0-9]\\w*$/;\n\n\ninternals.rule = Joi.object({\n alias: Joi.array().items(Joi.string().pattern(internals.nameRx)).single(),\n args: Joi.array().items(\n Joi.string(),\n Joi.object({\n name: Joi.string().pattern(internals.nameRx).required(),\n ref: Joi.boolean(),\n assert: Joi.alternatives([\n Joi.function(),\n Joi.object().schema()\n ])\n .conditional('ref', { is: true, then: Joi.required() }),\n normalize: Joi.function(),\n message: Joi.string().when('assert', { is: Joi.function(), then: Joi.required() })\n })\n ),\n convert: Joi.boolean(),\n manifest: Joi.boolean(),\n method: Joi.function().allow(false),\n multi: Joi.boolean(),\n validate: Joi.function(),\n jsonSchema: Joi.function()\n});\n\n\nexports.extension = Joi.object({\n type: Joi.alternatives([\n Joi.string(),\n Joi.object().regex()\n ])\n .required(),\n args: Joi.function(),\n cast: Joi.object().pattern(internals.nameRx, Joi.object({\n from: Joi.function().maxArity(1).required(),\n to: Joi.function().minArity(1).maxArity(2).required()\n })),\n base: Joi.object().schema()\n .when('type', { is: Joi.object().regex(), then: Joi.forbidden() }),\n coerce: [\n Joi.function().maxArity(3),\n Joi.object({ method: Joi.function().maxArity(3).required(), from: Joi.array().items(Joi.string()).single() })\n ],\n flags: Joi.object().pattern(internals.nameRx, Joi.object({\n setter: Joi.string(),\n default: Joi.any()\n })),\n manifest: {\n build: Joi.function().arity(2)\n },\n messages: [Joi.object(), Joi.string()],\n modifiers: Joi.object().pattern(internals.nameRx, Joi.function().minArity(1).maxArity(2)),\n overrides: Joi.object().pattern(internals.nameRx, Joi.function()),\n prepare: Joi.function().maxArity(3),\n rebuild: Joi.function().arity(1),\n rules: Joi.object().pattern(internals.nameRx, internals.rule),\n jsonSchema: Joi.function(),\n terms: Joi.object().pattern(internals.nameRx, Joi.object({\n init: Joi.array().allow(null).required(),\n manifest: Joi.object().pattern(/.+/, [\n Joi.valid('schema', 'single'),\n Joi.object({\n mapped: Joi.object({\n from: Joi.string().required(),\n to: Joi.string().required()\n })\n .required()\n })\n ])\n })),\n validate: Joi.function().maxArity(3)\n})\n .strict();\n\n\nexports.extensions = Joi.array().items(Joi.object(), Joi.function().arity(1)).strict();\n\n\n// Manifest\n\ninternals.desc = {\n\n buffer: Joi.object({\n buffer: Joi.string()\n }),\n\n func: Joi.object({\n function: Joi.function().required(),\n options: {\n literal: true\n }\n }),\n\n override: Joi.object({\n override: true\n }),\n\n ref: Joi.object({\n ref: Joi.object({\n type: Joi.valid('value', 'global', 'local'),\n path: Joi.array().required(),\n separator: Joi.string().length(1).allow(false),\n ancestor: Joi.number().min(0).integer().allow('root'),\n map: Joi.array().items(Joi.array().length(2)).min(1),\n adjust: Joi.function(),\n iterables: Joi.boolean(),\n in: Joi.boolean(),\n render: Joi.boolean()\n })\n .required()\n }),\n\n regex: Joi.object({\n regex: Joi.string().min(3)\n }),\n\n special: Joi.object({\n special: Joi.valid('deep').required()\n }),\n\n template: Joi.object({\n template: Joi.string().required(),\n options: Joi.object()\n }),\n\n value: Joi.object({\n value: Joi.alternatives([Joi.object(), Joi.array()]).required()\n })\n};\n\n\ninternals.desc.entity = Joi.alternatives([\n Joi.array().items(Joi.link('...')),\n Joi.boolean(),\n Joi.function(),\n Joi.number(),\n Joi.string(),\n internals.desc.buffer,\n internals.desc.func,\n internals.desc.ref,\n internals.desc.regex,\n internals.desc.special,\n internals.desc.template,\n internals.desc.value,\n Joi.link('/')\n]);\n\n\ninternals.desc.values = Joi.array()\n .items(\n null,\n Joi.boolean(),\n Joi.function(),\n Joi.number().allow(Infinity, -Infinity, NaN),\n Joi.string().allow(''),\n Joi.symbol(),\n internals.desc.buffer,\n internals.desc.func,\n internals.desc.override,\n internals.desc.ref,\n internals.desc.regex,\n internals.desc.template,\n internals.desc.value\n );\n\n\ninternals.desc.messages = Joi.object()\n .pattern(/.+/, [\n Joi.string(),\n internals.desc.template,\n Joi.object().pattern(/.+/, [Joi.string(), internals.desc.template])\n ]);\n\n\nexports.description = Joi.object({\n type: Joi.string().required(),\n flags: Joi.object({\n cast: Joi.string(),\n default: Joi.any(),\n description: Joi.string(),\n empty: Joi.link('/'),\n failover: internals.desc.entity,\n id: Joi.string(),\n label: Joi.string(),\n only: true,\n presence: ['optional', 'required', 'forbidden'],\n result: ['raw', 'strip'],\n strip: Joi.boolean(),\n unit: Joi.string()\n })\n .unknown(),\n preferences: {\n allowUnknown: Joi.boolean(),\n abortEarly: Joi.boolean(),\n artifacts: Joi.boolean(),\n cache: Joi.boolean(),\n convert: Joi.boolean(),\n dateFormat: ['date', 'iso', 'string', 'time', 'utc'],\n errors: {\n escapeHtml: Joi.boolean(),\n label: ['path', 'key'],\n language: [\n Joi.string(),\n internals.desc.ref\n ],\n wrap: {\n label: internals.wrap,\n array: internals.wrap\n }\n },\n externals: Joi.boolean(),\n messages: internals.desc.messages,\n noDefaults: Joi.boolean(),\n nonEnumerables: Joi.boolean(),\n presence: ['required', 'optional', 'forbidden'],\n skipFunctions: Joi.boolean(),\n stripUnknown: Joi.object({\n arrays: Joi.boolean(),\n objects: Joi.boolean()\n })\n .or('arrays', 'objects')\n .allow(true, false),\n warnings: Joi.boolean()\n },\n allow: internals.desc.values,\n invalid: internals.desc.values,\n rules: Joi.array().min(1).items({\n name: Joi.string().required(),\n args: Joi.object().min(1),\n keep: Joi.boolean(),\n message: [\n Joi.string(),\n internals.desc.messages\n ],\n warn: Joi.boolean()\n }),\n\n // Terms\n\n keys: Joi.object().pattern(/.*/, Joi.link('/')),\n link: internals.desc.ref\n})\n .pattern(/^[a-z]\\w*$/, Joi.any());\n","'use strict';\n\nconst internals = {\n operators: ['!', '^', '*', '/', '%', '+', '-', '<', '<=', '>', '>=', '==', '!=', '&&', '||', '??'],\n operatorCharacters: ['!', '^', '*', '/', '%', '+', '-', '<', '=', '>', '&', '|', '?'],\n operatorsOrder: [['^'], ['*', '/', '%'], ['+', '-'], ['<', '<=', '>', '>='], ['==', '!='], ['&&'], ['||', '??']],\n operatorsPrefix: ['!', 'n'],\n\n literals: {\n '\"': '\"',\n '`': '`',\n '\\'': '\\'',\n '[': ']'\n },\n\n numberRx: /^(?:[0-9]*(\\.[0-9]*)?){1}$/,\n tokenRx: /^[\\w\\$\\#\\.\\@\\:\\{\\}]+$/,\n\n symbol: Symbol('formula'),\n settings: Symbol('settings')\n};\n\n\nexports.Parser = class {\n\n constructor(string, options = {}) {\n\n if (!options[internals.settings] &&\n options.constants) {\n\n for (const constant in options.constants) {\n const value = options.constants[constant];\n if (value !== null &&\n !['boolean', 'number', 'string'].includes(typeof value)) {\n\n throw new Error(`Formula constant ${constant} contains invalid ${typeof value} value type`);\n }\n }\n }\n\n this.settings = options[internals.settings] ? options : Object.assign({ [internals.settings]: true, constants: {}, functions: {} }, options);\n this.single = null;\n\n this._parts = null;\n this._parse(string);\n }\n\n _parse(string) {\n\n let parts = [];\n let current = '';\n let parenthesis = 0;\n let literal = false;\n\n const flush = (inner) => {\n\n if (parenthesis) {\n throw new Error('Formula missing closing parenthesis');\n }\n\n const last = parts.length ? parts[parts.length - 1] : null;\n\n if (!literal &&\n !current &&\n !inner) {\n\n return;\n }\n\n if (last &&\n last.type === 'reference' &&\n inner === ')') { // Function\n\n last.type = 'function';\n last.value = this._subFormula(current, last.value);\n current = '';\n return;\n }\n\n if (inner === ')') { // Segment\n const sub = new exports.Parser(current, this.settings);\n parts.push({ type: 'segment', value: sub });\n }\n else if (literal) {\n if (literal === ']') { // Reference\n parts.push({ type: 'reference', value: current });\n current = '';\n return;\n }\n\n parts.push({ type: 'literal', value: current }); // Literal\n }\n else if (internals.operatorCharacters.includes(current)) { // Operator\n if (last &&\n last.type === 'operator' &&\n internals.operators.includes(last.value + current)) { // 2 characters operator\n\n last.value += current;\n }\n else {\n parts.push({ type: 'operator', value: current });\n }\n }\n else if (current.match(internals.numberRx)) { // Number\n parts.push({ type: 'constant', value: parseFloat(current) });\n }\n else if (this.settings.constants[current] !== undefined) { // Constant\n parts.push({ type: 'constant', value: this.settings.constants[current] });\n }\n else { // Reference\n if (!current.match(internals.tokenRx)) {\n throw new Error(`Formula contains invalid token: ${current}`);\n }\n\n parts.push({ type: 'reference', value: current });\n }\n\n current = '';\n };\n\n for (const c of string) {\n if (literal) {\n if (c === literal) {\n flush();\n literal = false;\n }\n else {\n current += c;\n }\n }\n else if (parenthesis) {\n if (c === '(') {\n current += c;\n ++parenthesis;\n }\n else if (c === ')') {\n --parenthesis;\n if (!parenthesis) {\n flush(c);\n }\n else {\n current += c;\n }\n }\n else {\n current += c;\n }\n }\n else if (c in internals.literals) {\n literal = internals.literals[c];\n }\n else if (c === '(') {\n flush();\n ++parenthesis;\n }\n else if (internals.operatorCharacters.includes(c)) {\n flush();\n current = c;\n flush();\n }\n else if (c !== ' ') {\n current += c;\n }\n else {\n flush();\n }\n }\n\n flush();\n\n // Replace prefix - to internal negative operator\n\n parts = parts.map((part, i) => {\n\n if (part.type !== 'operator' ||\n part.value !== '-' ||\n i && parts[i - 1].type !== 'operator') {\n\n return part;\n }\n\n return { type: 'operator', value: 'n' };\n });\n\n // Validate tokens order\n\n let operator = false;\n for (const part of parts) {\n if (part.type === 'operator') {\n if (internals.operatorsPrefix.includes(part.value)) {\n continue;\n }\n\n if (!operator) {\n throw new Error('Formula contains an operator in invalid position');\n }\n\n if (!internals.operators.includes(part.value)) {\n throw new Error(`Formula contains an unknown operator ${part.value}`);\n }\n }\n else if (operator) {\n throw new Error('Formula missing expected operator');\n }\n\n operator = !operator;\n }\n\n if (!operator) {\n throw new Error('Formula contains invalid trailing operator');\n }\n\n // Identify single part\n\n if (parts.length === 1 &&\n ['reference', 'literal', 'constant'].includes(parts[0].type)) {\n\n this.single = { type: parts[0].type === 'reference' ? 'reference' : 'value', value: parts[0].value };\n }\n\n // Process parts\n\n this._parts = parts.map((part) => {\n\n // Operators\n\n if (part.type === 'operator') {\n return internals.operatorsPrefix.includes(part.value) ? part : part.value;\n }\n\n // Literals, constants, segments\n\n if (part.type !== 'reference') {\n return part.value;\n }\n\n // References\n\n if (this.settings.tokenRx &&\n !this.settings.tokenRx.test(part.value)) {\n\n throw new Error(`Formula contains invalid reference ${part.value}`);\n }\n\n if (this.settings.reference) {\n return this.settings.reference(part.value);\n }\n\n return internals.reference(part.value);\n });\n }\n\n _subFormula(string, name) {\n\n const method = this.settings.functions[name];\n if (typeof method !== 'function') {\n throw new Error(`Formula contains unknown function ${name}`);\n }\n\n let args = [];\n if (string) {\n let current = '';\n let parenthesis = 0;\n let literal = false;\n\n const flush = () => {\n\n if (!current) {\n throw new Error(`Formula contains function ${name} with invalid arguments ${string}`);\n }\n\n args.push(current);\n current = '';\n };\n\n for (let i = 0; i < string.length; ++i) {\n const c = string[i];\n if (literal) {\n current += c;\n if (c === literal) {\n literal = false;\n }\n }\n else if (c in internals.literals &&\n !parenthesis) {\n\n current += c;\n literal = internals.literals[c];\n }\n else if (c === ',' &&\n !parenthesis) {\n\n flush();\n }\n else {\n current += c;\n if (c === '(') {\n ++parenthesis;\n }\n else if (c === ')') {\n --parenthesis;\n }\n }\n }\n\n flush();\n }\n\n args = args.map((arg) => new exports.Parser(arg, this.settings));\n\n return function (context) {\n\n const innerValues = [];\n for (const arg of args) {\n innerValues.push(arg.evaluate(context));\n }\n\n return method.call(context, ...innerValues);\n };\n }\n\n evaluate(context) {\n\n const parts = this._parts.slice();\n\n // Prefix operators\n\n for (let i = parts.length - 2; i >= 0; --i) {\n const part = parts[i];\n if (part &&\n part.type === 'operator') {\n\n const current = parts[i + 1];\n parts.splice(i + 1, 1);\n const value = internals.evaluate(current, context);\n parts[i] = internals.single(part.value, value);\n }\n }\n\n // Left-right operators\n\n internals.operatorsOrder.forEach((set) => {\n\n for (let i = 1; i < parts.length - 1;) {\n if (set.includes(parts[i])) {\n const operator = parts[i];\n const left = internals.evaluate(parts[i - 1], context);\n const right = internals.evaluate(parts[i + 1], context);\n\n parts.splice(i, 2);\n const result = internals.calculate(operator, left, right);\n parts[i - 1] = result === 0 ? 0 : result; // Convert -0\n }\n else {\n i += 2;\n }\n }\n });\n\n return internals.evaluate(parts[0], context);\n }\n};\n\n\nexports.Parser.prototype[internals.symbol] = true;\n\n\ninternals.reference = function (name) {\n\n return function (context) {\n\n return context && context[name] !== undefined ? context[name] : null;\n };\n};\n\n\ninternals.evaluate = function (part, context) {\n\n if (part === null) {\n return null;\n }\n\n if (typeof part === 'function') {\n return part(context);\n }\n\n if (part[internals.symbol]) {\n return part.evaluate(context);\n }\n\n return part;\n};\n\n\ninternals.single = function (operator, value) {\n\n if (operator === '!') {\n return value ? false : true;\n }\n\n // operator === 'n'\n\n const negative = -value;\n if (negative === 0) { // Override -0\n return 0;\n }\n\n return negative;\n};\n\n\ninternals.calculate = function (operator, left, right) {\n\n if (operator === '??') {\n return internals.exists(left) ? left :