Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic example is not working #96

Open
lapwat opened this issue Sep 23, 2020 · 0 comments
Open

Basic example is not working #96

lapwat opened this issue Sep 23, 2020 · 0 comments

Comments

@lapwat
Copy link

lapwat commented Sep 23, 2020

The example from the README is throwing an error. It is saying message: '"name" is required',.

const Joi = require('joi');
const Enjoi = require('enjoi');

const schema = Enjoi.schema({
    type: 'object',
    properties: {
        firstName: {
            description: 'First name.',
            type: 'string'
        },
        lastName: {
            description: 'Last name.',
            type: 'string'
        },
        age: {
            description: 'Age in years',
            type: 'integer',
            minimum: 1
        }
    },
    'required': ['firstName', 'lastName']
});

const { error, value } = schema.validate({firstName: 'John', lastName: 'Doe', age: 45});

Logs

/tmp/node_modules/@hapi/joi/lib/index.js:183
                throw error;
                ^

Error [ValidationError]: {
  "type": "object",
  "base": {
    "isJoi": true,
    "_type": "object",
    "_settings": null,
    "_valids": {
      "_set": {},
      "_hasRef": false
    },
    "_invalids": {
      "_set": {},
      "_hasRef": false
    },
    "_tests": [],
    "_refs": [],
    "_flags": {},
    "_description": null,
    "_unit": null,
    "_notes": [],
    "_tags": [],
    "_examples": [],
    "_meta": [],
    "_inner": {
      "children": null,
      "renames": [],
      "dependencies": [],
      "patterns": []
    },
    "_currentJoi": {
      "isJoi": true,
      "_currentJoi": "[Circular ~.base._currentJoi]",
      "_type": "any",
      "_settings": null,
      "_valids": {
        "_set": {},
        "_hasRef": false
      },
      "_invalids": {
        "_set": {},
        "_hasRef": false
      },
      "_tests": [],
      "_refs": [],
      "_flags": {},
      "_description": null,
      "_unit": null,
      "_notes": [],
      "_tags": [],
      "_examples": [],
      "_meta": [],
      "_inner": {},
      "_binds": {},
      "any": function (...args) {\n\n        Hoek.assert(args.length === 0, 'Joi.any() does not allow arguments.');\n\n        return internals.callWithDefaults.call(this, any, args);\n    },
      "alt": function (...args) {\n\n        return internals.callWithDefaults.call(this, internals.alternatives, args);\n    },
      "alternatives": function (...args) {\n\n        return internals.callWithDefaults.call(this, internals.alternatives, args);\n    },
      "array": function (...args) {\n\n        Hoek.assert(args.length === 0, 'Joi.array() does not allow arguments.');\n\n        return internals.callWithDefaults.call(this, internals.array, args);\n    },
      "bool": function (...args) {\n\n        Hoek.assert(args.length === 0, 'Joi.boolean() does not allow arguments.');\n\n        return internals.callWithDefaults.call(this, internals.boolean, args);\n    },
      "boolean": function (...args) {\n\n        Hoek.assert(args.length === 0, 'Joi.boolean() does not allow arguments.');\n\n        return internals.callWithDefaults.call(this, internals.boolean, args);\n    },
      "binary": function (...args) {\n\n        Hoek.assert(args.length === 0, 'Joi.binary() does not allow arguments.');\n\n        return internals.callWithDefaults.call(this, internals.binary, args);\n    },
      "date": function (...args) {\n\n        Hoek.assert(args.length === 0, 'Joi.date() does not allow arguments.');\n\n        return internals.callWithDefaults.call(this, internals.date, args);\n    },
      "func": function (...args) {\n\n        Hoek.assert(args.length === 0, 'Joi.func() does not allow arguments.');\n\n        return internals.callWithDefaults.call(this, internals.func, args);\n    },
      "number": function (...args) {\n\n        Hoek.assert(args.length === 0, 'Joi.number() does not allow arguments.');\n\n        return internals.callWithDefaults.call(this, internals.number, args);\n    },
      "object": function (...args) {\n\n        return internals.callWithDefaults.call(this, internals.object, args);\n    },
      "string": function (...args) {\n\n        Hoek.assert(args.length === 0, 'Joi.string() does not allow arguments.');\n\n        return internals.callWithDefaults.call(this, internals.string, args);\n    },
      "symbol": function (...args) {\n\n        Hoek.assert(args.length === 0, 'Joi.symbol() does not allow arguments.');\n\n        return internals.callWithDefaults.call(this, internals.symbol, args);\n    },
      "ref": function (...args) {\n\n        return Ref.create(...args);\n    },
      "isRef": function (ref) {\n\n        return Ref.isRef(ref);\n    },
      "validate": function (value, ...args /*, [schema], [options], callback */) {\n\n        const last = args[args.length - 1];\n        const callback = typeof last === 'function' ? last : null;\n\n        const count = args.length - (callback ? 1 : 0);\n        if (count === 0) {\n            return any.validate(value, callback);\n        }\n\n        const options = count === 2 ? args[1] : undefined;\n        const schema = this.compile(args[0]);\n\n        return schema._validateWithOptions(value, options, callback);\n    },
      "describe": function (...args) {\n\n        const schema = args.length ? this.compile(args[0]) : any;\n        return schema.describe();\n    },
      "compile": function (schema) {\n\n        try {\n            return Cast.schema(this, schema);\n        }\n        catch (err) {\n            if (err.hasOwnProperty('path')) {\n                err.message = err.message + '(' + err.path + ')';\n            }\n\n            throw err;\n        }\n    },
      "assert": function (value, schema, message) {\n\n        this.attempt(value, schema, message);\n    },
      "attempt": function (value, schema, message) {\n\n        const result = this.validate(value, schema);\n        const error = result.error;\n        if (error) {\n            if (!message) {\n                if (typeof error.annotate === 'function') {\n                    error.message = error.annotate();\n                }\n\n                throw error;\n            }\n\n            if (!(message instanceof Error)) {\n                if (typeof error.annotate === 'function') {\n                    error.message = `${message} ${error.annotate()}`;\n                }\n\n                throw error;\n            }\n\n            throw message;\n        }\n\n        return result.value;\n    },
      "reach": function (schema, path) {\n\n        Hoek.assert(schema && schema instanceof Any, 'you must provide a joi schema');\n        Hoek.assert(Array.isArray(path) || typeof path === 'string', 'path must be a string or an array of strings');\n\n        const reach = (sourceSchema, schemaPath) => {\n\n            if (!schemaPath.length) {\n                return sourceSchema;\n            }\n\n            const children = sourceSchema._inner.children;\n            if (!children) {\n                return;\n            }\n\n            const key = schemaPath.shift();\n            for (let i = 0; i < children.length; ++i) {\n                const child = children[i];\n                if (child.key === key) {\n                    return reach(child.schema, schemaPath);\n                }\n            }\n        };\n\n        const schemaPath = typeof path === 'string' ? (path ? path.split('.') : []) : path.slice();\n\n        return reach(schema, schemaPath);\n    },
      "lazy": function (...args) {\n\n        return internals.callWithDefaults.call(this, Lazy, args);\n    },
      "defaults": function (fn) {\n\n        Hoek.assert(typeof fn === 'function', 'Defaults must be a function');\n\n        let joi = Object.create(this.any());\n        joi = fn(joi);\n\n        Hoek.assert(joi && joi instanceof this.constructor, 'defaults() must return a schema');\n\n        Object.assign(joi, this, joi.clone()); // Re-add the types from `this` but also keep the settings from joi's potential new defaults\n\n        joi._defaults = (schema) => {\n\n            if (this._defaults) {\n                schema = this._defaults(schema);\n                Hoek.assert(schema instanceof this.constructor, 'defaults() must return a schema');\n            }\n\n            schema = fn(schema);\n            Hoek.assert(schema instanceof this.constructor, 'defaults() must return a schema');\n            return schema;\n        };\n\n        return joi;\n    },
      "bind": function () {\n\n        const joi = Object.create(this);\n\n        joi._binds.forEach((bind) => {\n\n            joi[bind] = joi[bind].bind(joi);\n        });\n\n        return joi;\n    },
      "extend": function (...args) {\n\n        const extensions = Hoek.flatten(args);\n        Hoek.assert(extensions.length > 0, 'You need to provide at least one extension');\n\n        this.assert(extensions, root.extensionsSchema);\n\n        const joi = Object.create(this.any());\n        Object.assign(joi, this);\n        joi._currentJoi = joi;\n        joi._binds = new Set(joi._binds);\n\n        for (let i = 0; i < extensions.length; ++i) {\n            let extension = extensions[i];\n\n            if (typeof extension === 'function') {\n                extension = extension(joi);\n            }\n\n            this.assert(extension, root.extensionSchema);\n\n            const base = (extension.base || this.any()).clone(); // Cloning because we're going to override language afterwards\n            const ctor = base.constructor;\n            const type = class extends ctor { // eslint-disable-line no-loop-func\n\n                constructor() {\n\n                    super();\n                    if (extension.base) {\n                        Object.assign(this, base);\n                    }\n\n                    this._type = extension.name;\n                }\n\n            };\n\n            if (extension.language) {\n                const lang = {\n                    [extension.name]: extension.language\n                };\n                type.prototype._language = Hoek.applyToDefaults(type.prototype._language || (base._settings && base._settings.language) || {}, lang);\n            }\n\n\n            if (extension.coerce) {\n                type.prototype._coerce = function (value, state, options) {\n\n                    if (ctor.prototype._coerce) {\n                        const baseRet = ctor.prototype._coerce.call(this, value, state, options);\n\n                        if (baseRet.errors) {\n                            return baseRet;\n                        }\n\n                        value = baseRet.value;\n                    }\n\n                    const ret = extension.coerce.call(this, value, state, options);\n                    if (ret instanceof Errors.Err) {\n                        return { value, errors: ret };\n                    }\n\n                    return { value: ret };\n                };\n            }\n\n            if (extension.pre) {\n                type.prototype._base = function (value, state, options) {\n\n                    if (ctor.prototype._base) {\n                        const baseRet = ctor.prototype._base.call(this, value, state, options);\n\n                        if (baseRet.errors) {\n                            return baseRet;\n                        }\n\n                        value = baseRet.value;\n                    }\n\n                    const ret = extension.pre.call(this, value, state, options);\n                    if (ret instanceof Errors.Err) {\n                        return { value, errors: ret };\n                    }\n\n                    return { value: ret };\n                };\n            }\n\n            if (extension.rules) {\n                for (let j = 0; j < extension.rules.length; ++j) {\n                    const rule = extension.rules[j];\n                    const ruleArgs = rule.params ?\n                        (rule.params instanceof Any ? rule.params._inner.children.map((k) => k.key) : Object.keys(rule.params)) :\n                        [];\n                    const validateArgs = rule.params ? Cast.schema(this, rule.params) : null;\n\n                    type.prototype[rule.name] = function (...rArgs) { // eslint-disable-line no-loop-func\n\n                        if (rArgs.length > ruleArgs.length) {\n                            throw new Error('Unexpected number of arguments');\n                        }\n\n                        let hasRef = false;\n                        let arg = {};\n\n                        for (let k = 0; k < ruleArgs.length; ++k) {\n                            arg[ruleArgs[k]] = rArgs[k];\n                            if (!hasRef && Ref.isRef(rArgs[k])) {\n                                hasRef = true;\n                            }\n                        }\n\n                        if (validateArgs) {\n                            arg = joi.attempt(arg, validateArgs);\n                        }\n\n                        let schema;\n                        if (rule.validate && !rule.setup) {\n                            const validate = function (value, state, options) {\n\n                                return rule.validate.call(this, arg, value, state, options);\n                            };\n\n                            schema = this._test(rule.name, arg, validate, {\n                                description: rule.description,\n                                hasRef\n                            });\n                        }\n                        else {\n                            schema = this.clone();\n                        }\n\n                        if (rule.setup) {\n                            const newSchema = rule.setup.call(schema, arg);\n                            if (newSchema !== undefined) {\n                                Hoek.assert(newSchema instanceof Any, `Setup of extension Joi.${this._type}().${rule.name}() must return undefined or a Joi object`);\n                                schema = newSchema;\n                            }\n\n                            if (rule.validate) {\n                                const validate = function (value, state, options) {\n\n                                    return rule.validate.call(this, arg, value, state, options);\n                                };\n\n                                schema = schema._test(rule.name, arg, validate, {\n                                    description: rule.description,\n                                    hasRef\n                                });\n                            }\n                        }\n\n                        return schema;\n                    };\n                }\n            }\n\n            if (extension.describe) {\n                type.prototype.describe = function () {\n\n                    const description = ctor.prototype.describe.call(this);\n                    return extension.describe.call(this, description);\n                };\n            }\n\n            const instance = new type();\n            joi[extension.name] = function (...extArgs) {\n\n                return internals.callWithDefaults.call(this, instance, extArgs);\n            };\n\n            joi._binds.add(extension.name);\n        }\n\n        return joi;\n    },
      "extensionSchema": {
        "isJoi": true,
        "_currentJoi": "[Circular ~.base._currentJoi]",
        "_type": "object",
        "_settings": {
          "convert": false
        },
        "_valids": {
          "_set": {},
          "_hasRef": false
        },
        "_invalids": {
          "_set": {},
          "_hasRef": false
        },
        "_tests": [],
        "_refs": [],
        "_flags": {},
        "_description": null,
        "_unit": null,
        "_notes": [],
        "_tags": [],
        "_examples": [],
        "_meta": [],
        "_inner": {
          "children": [
            {
              "key": "base",
              "schema": {
                "isJoi": true,
                "_currentJoi": "[Circular ~.base._currentJoi]",
                "_type": "object",
                "_settings": null,
                "_valids": {
                  "_set": {},
                  "_hasRef": false
                },
                "_invalids": {
                  "_set": {},
                  "_hasRef": false
                },
                "_tests": [
                  {
                    "func": function (value, state, options) {\n\n            if (value instanceof constructor) {\n                return value;\n            }\n\n            return this.createError('object.type', { type: typeData.name, value }, state, options);\n        },
                    "name": "type",
                    "arg": {
                      "name": "Joi object",
                      "ctor": "[class {\n\n    constructor() {\n\n        this.isJoi = true;\n        this._type = 'any';\n        this._settings = null;\n        this._valids = new internals.Set();\n        this._invalids = new internals.Set();\n        this._tests = [];\n        this._refs = [];\n        this._flags = {\n            /*\n             presence: 'optional',                   // optional, required, forbidden, ignore\n             allowOnly: false,\n             allowUnknown: undefined,\n             default: undefined,\n             forbidden: false,\n             encoding: undefined,\n             insensitive: false,\n             trim: false,\n             normalize: undefined,                   // NFC, NFD, NFKC, NFKD\n             case: undefined,                        // upper, lower\n             empty: undefined,\n             func: false,\n             raw: false\n             */\n        };\n\n        this._description = null;\n        this._unit = null;\n        this._notes = [];\n        this._tags = [];\n        this._examples = [];\n        this._meta = [];\n\n        this._inner = {};                           // Hash of arrays of immutable objects\n    }\n\n    _init() {\n\n        return this;\n    }\n\n    get schemaType() {\n\n        return this._type;\n    }\n\n    createError(type, context, state, options, flags = this._flags) {\n\n        return Errors.create(type, context, state, options, flags);\n    }\n\n    createOverrideError(type, context, state, options, message, template) {\n\n        return Errors.create(type, context, state, options, this._flags, message, template);\n    }\n\n    checkOptions(options) {\n\n        Schemas = Schemas || require('../../schemas');\n\n        const result = Schemas.options.validate(options);\n\n        if (result.error) {\n            throw new Error(result.error.details[0].message);\n        }\n    }\n\n    clone() {\n\n        const obj = Object.create(Object.getPrototypeOf(this));\n\n        obj.isJoi = true;\n        obj._currentJoi = this._currentJoi;\n        obj._type = this._type;\n        obj._settings = this._settings;\n        obj._baseType = this._baseType;\n        obj._valids = this._valids.slice();\n        obj._invalids = this._invalids.slice();\n        obj._tests = this._tests.slice();\n        obj._refs = this._refs.slice();\n        obj._flags = Hoek.clone(this._flags);\n\n        obj._description = this._description;\n        obj._unit = this._unit;\n        obj._notes = this._notes.slice();\n        obj._tags = this._tags.slice();\n        obj._examples = this._examples.slice();\n        obj._meta = this._meta.slice();\n\n        obj._inner = {};\n        const inners = Object.keys(this._inner);\n        for (let i = 0; i < inners.length; ++i) {\n            const key = inners[i];\n            obj._inner[key] = this._inner[key] ? this._inner[key].slice() : null;\n        }\n\n        return obj;\n    }\n\n    concat(schema) {\n\n        Hoek.assert(schema instanceof internals.Any, 'Invalid schema object');\n        Hoek.assert(this._type === 'any' || schema._type === 'any' || schema._type === this._type, 'Cannot merge type', this._type, 'with another type:', schema._type);\n\n        let obj = this.clone();\n\n        if (this._type === 'any' && schema._type !== 'any') {\n\n            // Reset values as if we were \"this\"\n            const tmpObj = schema.clone();\n            const keysToRestore = ['_settings', '_valids', '_invalids', '_tests', '_refs', '_flags', '_description', '_unit',\n                '_notes', '_tags', '_examples', '_meta', '_inner'];\n\n            for (let i = 0; i < keysToRestore.length; ++i) {\n                tmpObj[keysToRestore[i]] = obj[keysToRestore[i]];\n            }\n\n            obj = tmpObj;\n        }\n\n        obj._settings = obj._settings ? Settings.concat(obj._settings, schema._settings) : schema._settings;\n        obj._valids.merge(schema._valids, schema._invalids);\n        obj._invalids.merge(schema._invalids, schema._valids);\n        obj._tests.push(...schema._tests);\n        obj._refs.push(...schema._refs);\n        if (obj._flags.empty && schema._flags.empty) {\n            obj._flags.empty = obj._flags.empty.concat(schema._flags.empty);\n            const flags = Object.assign({}, schema._flags);\n            delete flags.empty;\n            Hoek.merge(obj._flags, flags);\n        }\n        else if (schema._flags.empty) {\n            obj._flags.empty = schema._flags.empty;\n            const flags = Object.assign({}, schema._flags);\n            delete flags.empty;\n            Hoek.merge(obj._flags, flags);\n        }\n        else {\n            Hoek.merge(obj._flags, schema._flags);\n        }\n\n        obj._description = schema._description || obj._description;\n        obj._unit = schema._unit || obj._unit;\n        obj._notes.push(...schema._notes);\n        obj._tags.push(...schema._tags);\n        obj._examples.push(...schema._examples);\n        obj._meta.push(...schema._meta);\n\n        const inners = Object.keys(schema._inner);\n        const isObject = obj._type === 'object';\n        for (let i = 0; i < inners.length; ++i) {\n            const key = inners[i];\n            const source = schema._inner[key];\n            if (source) {\n                const target = obj._inner[key];\n                if (target) {\n                    if (isObject && key === 'children') {\n                        const keys = {};\n\n                        for (let j = 0; j < target.length; ++j) {\n                            keys[target[j].key] = j;\n                        }\n\n                        for (let j = 0; j < source.length; ++j) {\n                            const sourceKey = source[j].key;\n                            if (keys[sourceKey] >= 0) {\n                                target[keys[sourceKey]] = {\n                                    key: sourceKey,\n                                    schema: target[keys[sourceKey]].schema.concat(source[j].schema)\n                                };\n                            }\n                            else {\n                                target.push(source[j]);\n                            }\n                        }\n                    }\n                    else {\n                        obj._inner[key] = obj._inner[key].concat(source);\n                    }\n                }\n                else {\n                    obj._inner[key] = source.slice();\n                }\n            }\n        }\n\n        return obj;\n    }\n\n    _test(name, arg, func, options) {\n\n        const obj = this.clone();\n        obj._tests.push({ func, name, arg, options });\n        return obj;\n    }\n\n    _testUnique(name, arg, func, options) {\n\n        const obj = this.clone();\n        obj._tests = obj._tests.filter((test) => test.name !== name);\n        obj._tests.push({ func, name, arg, options });\n        return obj;\n    }\n\n    options(options) {\n\n        Hoek.assert(!options.context, 'Cannot override context');\n        this.checkOptions(options);\n\n        const obj = this.clone();\n        obj._settings = Settings.concat(obj._settings, options);\n        return obj;\n    }\n\n    strict(isStrict) {\n\n        const obj = this.clone();\n\n        const convert = isStrict === undefined ? false : !isStrict;\n        obj._settings = Settings.concat(obj._settings, { convert });\n        return obj;\n    }\n\n    raw(isRaw) {\n\n        const value = isRaw === undefined ? true : isRaw;\n\n        if (this._flags.raw === value) {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.raw = value;\n        return obj;\n    }\n\n    error(err, options = { self: false }) {\n\n        Hoek.assert(err && (err instanceof Error || typeof err === 'function'), 'Must provide a valid Error object or a function');\n\n        const unknownKeys = Object.keys(options).filter((k) => !['self'].includes(k));\n        Hoek.assert(unknownKeys.length === 0, `Options ${unknownKeys} are unknown`);\n\n        const obj = this.clone();\n        obj._flags.error = err;\n\n        if (options.self) {\n            obj._flags.selfError = true;\n        }\n\n        return obj;\n    }\n\n    allow(...values) {\n\n        const obj = this.clone();\n        values = Hoek.flatten(values);\n        for (let i = 0; i < values.length; ++i) {\n            const value = values[i];\n\n            Hoek.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');\n            obj._invalids.remove(value);\n            obj._valids.add(value, obj._refs);\n        }\n\n        return obj;\n    }\n\n    valid(...values) {\n\n        const obj = this.allow(...values);\n        obj._flags.allowOnly = true;\n        return obj;\n    }\n\n    invalid(...values) {\n\n        const obj = this.clone();\n        values = Hoek.flatten(values);\n        for (let i = 0; i < values.length; ++i) {\n            const value = values[i];\n\n            Hoek.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');\n            obj._valids.remove(value);\n            obj._invalids.add(value, obj._refs);\n        }\n\n        return obj;\n    }\n\n    required() {\n\n        if (this._flags.presence === 'required') {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.presence = 'required';\n        return obj;\n    }\n\n    optional() {\n\n        if (this._flags.presence === 'optional') {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.presence = 'optional';\n        return obj;\n    }\n\n\n    forbidden() {\n\n        if (this._flags.presence === 'forbidden') {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.presence = 'forbidden';\n        return obj;\n    }\n\n\n    strip() {\n\n        if (this._flags.strip) {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.strip = true;\n        return obj;\n    }\n\n    applyFunctionToChildren(children, fn, args = [], root) {\n\n        children = [].concat(children);\n\n        if (children.length !== 1 || children[0] !== '') {\n            root = root ? (root + '.') : '';\n\n            const extraChildren = (children[0] === '' ? children.slice(1) : children).map((child) => {\n\n                return root + child;\n            });\n\n            throw new Error('unknown key(s) ' + extraChildren.join(', '));\n        }\n\n        return this[fn](...args);\n    }\n\n    default(value, description) {\n\n        if (typeof value === 'function' &&\n            !Ref.isRef(value)) {\n\n            if (!value.description &&\n                description) {\n\n                value.description = description;\n            }\n\n            if (!this._flags.func) {\n                Hoek.assert(typeof value.description === 'string' && value.description.length > 0, 'description must be provided when default value is a function');\n            }\n        }\n\n        const obj = this.clone();\n        obj._flags.default = value;\n        Ref.push(obj._refs, value);\n        return obj;\n    }\n\n    empty(schema) {\n\n        const obj = this.clone();\n        if (schema === undefined) {\n            delete obj._flags.empty;\n        }\n        else {\n            obj._flags.empty = Cast.schema(this._currentJoi, schema);\n        }\n\n        return obj;\n    }\n\n    when(condition, options) {\n\n        Hoek.assert(options && typeof options === 'object', 'Invalid options');\n        Hoek.assert(options.then !== undefined || options.otherwise !== undefined, 'options must have at least one of \"then\" or \"otherwise\"');\n\n        const then = options.hasOwnProperty('then') ? this.concat(Cast.schema(this._currentJoi, options.then)) : undefined;\n        const otherwise = options.hasOwnProperty('otherwise') ? this.concat(Cast.schema(this._currentJoi, options.otherwise)) : undefined;\n\n        Alternatives = Alternatives || require('../alternatives');\n\n        const alternativeOptions = { then, otherwise };\n        if (Object.prototype.hasOwnProperty.call(options, 'is')) {\n            alternativeOptions.is = options.is;\n        }\n\n        const obj = Alternatives.when(condition, alternativeOptions);\n        obj._flags.presence = 'ignore';\n        obj._baseType = this;\n\n        return obj;\n    }\n\n    description(desc) {\n\n        Hoek.assert(desc && typeof desc === 'string', 'Description must be a non-empty string');\n\n        const obj = this.clone();\n        obj._description = desc;\n        return obj;\n    }\n\n    notes(notes) {\n\n        Hoek.assert(notes && (typeof notes === 'string' || Array.isArray(notes)), 'Notes must be a non-empty string or array');\n\n        const obj = this.clone();\n        obj._notes = obj._notes.concat(notes);\n        return obj;\n    }\n\n    tags(tags) {\n\n        Hoek.assert(tags && (typeof tags === 'string' || Array.isArray(tags)), 'Tags must be a non-empty string or array');\n\n        const obj = this.clone();\n        obj._tags = obj._tags.concat(tags);\n        return obj;\n    }\n\n    meta(meta) {\n\n        Hoek.assert(meta !== undefined, 'Meta cannot be undefined');\n\n        const obj = this.clone();\n        obj._meta = obj._meta.concat(meta);\n        return obj;\n    }\n\n    example(...examples) {\n\n        Hoek.assert(examples.length > 0, 'Missing examples');\n\n        const processed = [];\n        for (let i = 0; i < examples.length; ++i) {\n            const example = [].concat(examples[i]);\n            Hoek.assert(example.length <= 2, `Bad example format at index ${i}`);\n\n            const value = example[0];\n            let options = example[1];\n            if (options !== undefined) {\n                Hoek.assert(options && typeof options === 'object', `Options for example at index ${i} must be an object`);\n                const unknownOptions = Object.keys(options).filter((option) => !['parent', 'context'].includes(option));\n                Hoek.assert(unknownOptions.length === 0, `Unknown example options ${unknownOptions} at index ${i}`);\n            }\n            else {\n                options = {};\n            }\n\n            const localState = new State('', [], options.parent || null);\n            const result = this._validate(value, localState, Settings.concat(internals.defaults, options.context ? { context: options.context } : null));\n            Hoek.assert(!result.errors, `Bad example at index ${i}:`, result.errors && Errors.process(result.errors, value));\n\n            const ex = { value };\n            if (Object.keys(options).length) {\n                ex.options = options;\n            }\n\n            processed.push(ex);\n        }\n\n        const obj = this.clone();\n        obj._examples = processed;\n        return obj;\n    }\n\n    unit(name) {\n\n        Hoek.assert(name && typeof name === 'string', 'Unit name must be a non-empty string');\n\n        const obj = this.clone();\n        obj._unit = name;\n        return obj;\n    }\n\n    _prepareEmptyValue(value) {\n\n        if (typeof value === 'string' && this._flags.trim) {\n            return value.trim();\n        }\n\n        return value;\n    }\n\n    _validate(value, state, options, reference) {\n\n        const originalValue = value;\n\n        // Setup state and settings\n\n        state = state || new State('', [], null, reference);\n\n        if (this._settings) {\n            const isDefaultOptions = options === internals.defaults;\n            if (isDefaultOptions && this._settings[Symbols.settingsCache]) {\n                options = this._settings[Symbols.settingsCache];\n            }\n            else {\n                options = Settings.concat(this._language ? Settings.concat({ language: this._language }, options) : options, this._settings);\n                if (isDefaultOptions) {\n                    this._settings[Symbols.settingsCache] = options;\n                }\n            }\n        }\n        else if (this._language) {\n            options = Settings.concat({ language: this._language }, options);\n        }\n\n        let errors = [];\n\n        if (this._coerce) {\n            const coerced = this._coerce(value, state, options);\n            if (coerced.errors) {\n                value = coerced.value;\n                errors = errors.concat(coerced.errors);\n                return this._finalizeValue(value, originalValue, errors, state, options);                            // Coerced error always aborts early\n            }\n\n            value = coerced.value;\n        }\n\n        if (this._flags.empty && !this._flags.empty._validate(this._prepareEmptyValue(value), null, internals.defaults).errors) {\n            value = undefined;\n        }\n\n        // Check presence requirements\n\n        const presence = this._flags.presence || options.presence;\n        if (presence === 'optional') {\n            if (value === undefined) {\n                const isDeepDefault = this._flags.hasOwnProperty('default') && this._flags.default === undefined;\n                if (isDeepDefault && this._type === 'object') {\n                    value = {};\n                }\n                else {\n                    return this._finalizeValue(value, originalValue, errors, state, options);\n                }\n            }\n        }\n        else if (presence === 'required' &&\n            value === undefined) {\n\n            errors.push(this.createError('any.required', null, state, options));\n            return this._finalizeValue(value, originalValue, errors, state, options);\n        }\n        else if (presence === 'forbidden') {\n            if (value === undefined) {\n                return this._finalizeValue(value, originalValue, errors, state, options);\n            }\n\n            errors.push(this.createError('any.unknown', null, state, options));\n            return this._finalizeValue(value, originalValue, errors, state, options);\n        }\n\n        // Check allowed and denied values using the original value\n\n        let match = this._valids.get(value, state, options, this._flags.insensitive);\n        if (match) {\n            if (options.convert) {\n                value = match.value;\n            }\n\n            return this._finalizeValue(value, originalValue, errors, state, options);\n        }\n\n        if (this._invalids.has(value, state, options, this._flags.insensitive)) {\n            errors.push(this.createError(value === '' ? 'any.empty' : 'any.invalid', { value, invalids: this._invalids.values({ stripUndefined: true }) }, state, options));\n            if (options.abortEarly) {\n\n                return this._finalizeValue(value, originalValue, errors, state, options);\n            }\n        }\n\n        // Convert value and validate type\n\n        if (this._base) {\n            const base = this._base(value, state, options);\n            if (base.errors) {\n                value = base.value;\n                errors = errors.concat(base.errors);\n                return this._finalizeValue(value, originalValue, errors, state, options);                            // Base error always aborts early\n            }\n\n            if (base.value !== value) {\n                value = base.value;\n\n                // Check allowed and denied values using the converted value\n\n                match = this._valids.get(value, state, options, this._flags.insensitive);\n                if (match) {\n                    value = match.value;\n                    return this._finalizeValue(value, originalValue, errors, state, options);\n                }\n\n                if (this._invalids.has(value, state, options, this._flags.insensitive)) {\n                    errors.push(this.createError(value === '' ? 'any.empty' : 'any.invalid', { value, invalids: this._invalids.values({ stripUndefined: true }) }, state, options));\n                    if (options.abortEarly) {\n                        return this._finalizeValue(value, originalValue, errors, state, options);\n                    }\n                }\n            }\n        }\n\n        // Required values did not match\n\n        if (this._flags.allowOnly) {\n            errors.push(this.createError('any.allowOnly', { value, valids: this._valids.values({ stripUndefined: true }) }, state, options));\n            if (options.abortEarly) {\n                return this._finalizeValue(value, originalValue, errors, state, options);\n            }\n        }\n\n        // Validate tests\n\n        for (let i = 0; i < this._tests.length; ++i) {\n            const test = this._tests[i];\n            const ret = test.func.call(this, value, state, options);\n            if (ret instanceof Errors.Err) {\n                errors.push(ret);\n                if (options.abortEarly) {\n                    return this._finalizeValue(value, originalValue, errors, state, options);\n                }\n            }\n            else {\n                value = ret;\n            }\n        }\n\n        return this._finalizeValue(value, originalValue, errors, state, options);\n    }\n\n    _finalizeValue(value, originalValue, errors, state, options) {\n\n        let finalValue;\n\n        if (value !== undefined) {\n            finalValue = this._flags.raw ? originalValue : value;\n        }\n        else if (options.noDefaults) {\n            finalValue = value;\n        }\n        else if (Ref.isRef(this._flags.default)) {\n            finalValue = this._flags.default(state.parent, options);\n        }\n        else if (typeof this._flags.default === 'function' &&\n            !(this._flags.func && !this._flags.default.description)) {\n\n            let args;\n\n            if (state.parent !== null &&\n                this._flags.default.length > 0) {\n\n                args = [Hoek.clone(state.parent), options];\n            }\n\n            const defaultValue = internals._try(this._flags.default, args);\n            finalValue = defaultValue.value;\n            if (defaultValue.error) {\n                errors.push(this.createError('any.default', { error: defaultValue.error }, state, options));\n            }\n        }\n        else {\n            finalValue = Hoek.clone(this._flags.default);\n        }\n\n        if (errors.length &&\n            typeof this._flags.error === 'function' &&\n            (\n                !this._flags.selfError ||\n                errors.some((e) => state.path.length === e.path.length)\n            )\n        ) {\n            const change = this._flags.error.call(this, errors);\n\n            if (typeof change === 'string') {\n                errors = [this.createOverrideError('override', { reason: errors }, state, options, change)];\n            }\n            else {\n                errors = [].concat(change)\n                    .map((err) => {\n\n                        return err instanceof Error ?\n                            err :\n                            this.createOverrideError(err.type || 'override', err.context, state, options, err.message, err.template);\n                    });\n            }\n        }\n\n        return {\n            value: this._flags.strip ? undefined : finalValue,\n            finalValue,\n            errors: errors.length ? errors : null\n        };\n    }\n\n    _validateWithOptions(value, options, callback) {\n\n        if (options) {\n            this.checkOptions(options);\n        }\n\n        const settings = Settings.concat(internals.defaults, options);\n        const result = this._validate(value, null, settings);\n        const errors = Errors.process(result.errors, value);\n\n        if (callback) {\n            return callback(errors, result.value);\n        }\n\n        return {\n            error: errors,\n            value: result.value,\n            then(resolve, reject) {\n\n                if (errors) {\n                    return Promise.reject(errors).catch(reject);\n                }\n\n                return Promise.resolve(result.value).then(resolve);\n            },\n            catch(reject) {\n\n                if (errors) {\n                    return Promise.reject(errors).catch(reject);\n                }\n\n                return Promise.resolve(result.value);\n            }\n        };\n    }\n\n    validate(value, options, callback) {\n\n        if (typeof options === 'function') {\n            return this._validateWithOptions(value, null, options);\n        }\n\n        return this._validateWithOptions(value, options, callback);\n    }\n\n    describe() {\n\n        const description = {\n            type: this._type\n        };\n\n        const flags = Object.keys(this._flags);\n        if (flags.length) {\n            if (['empty', 'default', 'lazy', 'label'].some((flag) => this._flags.hasOwnProperty(flag))) {\n                description.flags = {};\n                for (let i = 0; i < flags.length; ++i) {\n                    const flag = flags[i];\n                    if (flag === 'empty') {\n                        description.flags[flag] = this._flags[flag].describe();\n                    }\n                    else if (flag === 'default') {\n                        if (Ref.isRef(this._flags[flag])) {\n                            description.flags[flag] = this._flags[flag].toString();\n                        }\n                        else if (typeof this._flags[flag] === 'function') {\n                            description.flags[flag] = {\n                                description: this._flags[flag].description,\n                                function   : this._flags[flag]\n                            };\n                        }\n                        else {\n                            description.flags[flag] = this._flags[flag];\n                        }\n                    }\n                    else if (flag === 'lazy' || flag === 'label') {\n                        // We don't want it in the description\n                    }\n                    else {\n                        description.flags[flag] = this._flags[flag];\n                    }\n                }\n            }\n            else {\n                description.flags = this._flags;\n            }\n        }\n\n        if (this._settings) {\n            description.options = Hoek.clone(this._settings);\n        }\n\n        if (this._baseType) {\n            description.base = this._baseType.describe();\n        }\n\n        if (this._description) {\n            description.description = this._description;\n        }\n\n        if (this._notes.length) {\n            description.notes = this._notes;\n        }\n\n        if (this._tags.length) {\n            description.tags = this._tags;\n        }\n\n        if (this._meta.length) {\n            description.meta = this._meta;\n        }\n\n        if (this._examples.length) {\n            description.examples = this._examples;\n        }\n\n        if (this._unit) {\n            description.unit = this._unit;\n        }\n\n        const valids = this._valids.values();\n        if (valids.length) {\n            description.valids = valids.map((v) => {\n\n                return Ref.isRef(v) ? v.toString() : v;\n            });\n        }\n\n        const invalids = this._invalids.values();\n        if (invalids.length) {\n            description.invalids = invalids.map((v) => {\n\n                return Ref.isRef(v) ? v.toString() : v;\n            });\n        }\n\n        description.rules = [];\n\n        for (let i = 0; i < this._tests.length; ++i) {\n            const validator = this._tests[i];\n            const item = { name: validator.name };\n\n            if (validator.arg !== void 0) {\n                item.arg = Ref.isRef(validator.arg) ? validator.arg.toString() : validator.arg;\n            }\n\n            const options = validator.options;\n            if (options) {\n                if (options.hasRef) {\n                    item.arg = {};\n                    const keys = Object.keys(validator.arg);\n                    for (let j = 0; j < keys.length; ++j) {\n                        const key = keys[j];\n                        const value = validator.arg[key];\n                        item.arg[key] = Ref.isRef(value) ? value.toString() : value;\n                    }\n                }\n\n                if (typeof options.description === 'string') {\n                    item.description = options.description;\n                }\n                else if (typeof options.description === 'function') {\n                    item.description = options.description(item.arg);\n                }\n            }\n\n            description.rules.push(item);\n        }\n\n        if (!description.rules.length) {\n            delete description.rules;\n        }\n\n        const label = this._getLabel();\n        if (label) {\n            description.label = label;\n        }\n\n        return description;\n    }\n\n    label(name) {\n\n        Hoek.assert(name && typeof name === 'string', 'Label name must be a non-empty string');\n\n        const obj = this.clone();\n        obj._flags.label = name;\n        return obj;\n    }\n\n    _getLabel(def) {\n\n        return this._flags.label || def;\n    }\n\n}]"
                    }
                  }
                ],
                "_refs": [],
                "_flags": {},
                "_description": null,
                "_unit": null,
                "_notes": [],
                "_tags": [],
                "_examples": [],
                "_meta": [],
                "_inner": {
                  "children": null,
                  "renames": [],
                  "dependencies": [],
                  "patterns": []
                }
              }
            },
            {
              "key": "name",
              "schema": {
                "isJoi": true,
                "_currentJoi": "[Circular ~.base._currentJoi]",
                "_type": "string",
                "_settings": null,
                "_valids": {
                  "_set": {},
                  "_hasRef": false
                },
                "_invalids": {
                  "_set": {},
                  "_hasRef": 0
                },
                "_tests": [],
                "_refs": [],
                "_flags": {
                  "presence": "required"
                },
                "_description": null,
                "_unit": null,
                "_notes": [],
                "_tags": [],
                "_examples": [],
                "_meta": [],
                "_inner": {}
              }
            },
            {
              "key": "coerce",
              "schema": {
                "isJoi": true,
                "_currentJoi": "[Circular ~.base._currentJoi]",
                "_type": "object",
                "_settings": null,
                "_valids": {
                  "_set": {},
                  "_hasRef": false
                },
                "_invalids": {
                  "_set": {},
                  "_hasRef": false
                },
                "_tests": [
                  {
                    "func": function (value, state, options) {\n\n            if (value.length === n) {\n                return value;\n            }\n\n            return this.createError('function.arity', { n }, state, options);\n        },
                    "name": "arity",
                    "arg": 3
                  }
                ],
                "_refs": [],
                "_flags": {
                  "func": true
                },
                "_description": null,
                "_unit": null,
                "_notes": [],
                "_tags": [],
                "_examples": [],
                "_meta": [],
                "_inner": {
                  "children": null,
                  "renames": [],
                  "dependencies": [],
                  "patterns": []
                }
              }
            },
            {
              "key": "pre",
              "schema": {
                "isJoi": true,
                "_currentJoi": "[Circular ~.base._currentJoi]",
                "_type": "object",
                "_settings": null,
                "_valids": {
                  "_set": {},
                  "_hasRef": false
                },
                "_invalids": {
                  "_set": {},
                  "_hasRef": false
                },
                "_tests": [
                  {
                    "func": function (value, state, options) {\n\n            if (value.length === n) {\n                return value;\n            }\n\n            return this.createError('function.arity', { n }, state, options);\n        },
                    "name": "arity",
                    "arg": 3
                  }
                ],
                "_refs": [],
                "_flags": {
                  "func": true
                },
                "_description": null,
                "_unit": null,
                "_notes": [],
                "_tags": [],
                "_examples": [],
                "_meta": [],
                "_inner": {
                  "children": null,
                  "renames": [],
                  "dependencies": [],
                  "patterns": []
                }
              }
            },
            {
              "key": "language",
              "schema": "[Circular ~.base]"
            },
            {
              "key": "describe",
              "schema": {
                "isJoi": true,
                "_currentJoi": "[Circular ~.base._currentJoi]",
                "_type": "object",
                "_settings": null,
                "_valids": {
                  "_set": {},
                  "_hasRef": false
                },
                "_invalids": {
                  "_set": {},
                  "_hasRef": false
                },
                "_tests": [
                  {
                    "func": function (value, state, options) {\n\n            if (value.length === n) {\n                return value;\n            }\n\n            return this.createError('function.arity', { n }, state, options);\n        },
                    "name": "arity",
                    "arg": 1
                  }
                ],
                "_refs": [],
                "_flags": {
                  "func": true
                },
                "_description": null,
                "_unit": null,
                "_notes": [],
                "_tags": [],
                "_examples": [],
                "_meta": [],
                "_inner": {
                  "children": null,
                  "renames": [],
                  "dependencies": [],
                  "patterns": []
                }
              }
            },
            {
              "key": "rules",
              "schema": {
                "isJoi": true,
                "_currentJoi": "[Circular ~.base._currentJoi]",
                "_type": "array",
                "_settings": null,
                "_valids": {
                  "_set": {},
                  "_hasRef": false
                },
                "_invalids": {
                  "_set": {},
                  "_hasRef": false
                },
                "_tests": [],
                "_refs": [],
                "_flags": {
                  "sparse": false
                },
                "_description": null,
                "_unit": null,
                "_notes": [],
                "_tags": [],
                "_examples": [],
                "_meta": [],
                "_inner": {
                  "items": [
                    {
                      "isJoi": true,
                      "_currentJoi": "[Circular ~.base._currentJoi]",
                      "_type": "object",
                      "_settings": null,
                      "_valids": {
                        "_set": {},
                        "_hasRef": false
                      },
                      "_invalids": {
                        "_set": {},
                        "_hasRef": false
                      },
                      "_tests": [],
                      "_refs": [],
                      "_flags": {},
                      "_description": null,
                      "_unit": null,
                      "_notes": [],
                      "_tags": [],
                      "_examples": [],
                      "_meta": [],
                      "_inner": {
                        "children": [
                          {
                            "key": "name",
                            "schema": {
                              "isJoi": true,
                              "_currentJoi": "[Circular ~.base._currentJoi]",
                              "_type": "string",
                              "_settings": null,
                              "_valids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_invalids": {
                                "_set": {},
                                "_hasRef": 0
                              },
                              "_tests": [],
                              "_refs": [],
                              "_flags": {
                                "presence": "required"
                              },
                              "_description": null,
                              "_unit": null,
                              "_notes": [],
                              "_tags": [],
                              "_examples": [],
                              "_meta": [],
                              "_inner": {}
                            }
                          },
                          {
                            "key": "setup",
                            "schema": {
                              "isJoi": true,
                              "_currentJoi": "[Circular ~.base._currentJoi]",
                              "_type": "object",
                              "_settings": null,
                              "_valids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_invalids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_tests": [
                                {
                                  "func": function (value, state, options) {\n\n            if (value.length === n) {\n                return value;\n            }\n\n            return this.createError('function.arity', { n }, state, options);\n        },
                                  "name": "arity",
                                  "arg": 1
                                }
                              ],
                              "_refs": [],
                              "_flags": {
                                "func": true
                              },
                              "_description": null,
                              "_unit": null,
                              "_notes": [],
                              "_tags": [],
                              "_examples": [],
                              "_meta": [],
                              "_inner": {
                                "children": null,
                                "renames": [],
                                "dependencies": [],
                                "patterns": []
                              }
                            }
                          },
                          {
                            "key": "validate",
                            "schema": {
                              "isJoi": true,
                              "_currentJoi": "[Circular ~.base._currentJoi]",
                              "_type": "object",
                              "_settings": null,
                              "_valids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_invalids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_tests": [
                                {
                                  "func": function (value, state, options) {\n\n            if (value.length === n) {\n                return value;\n            }\n\n            return this.createError('function.arity', { n }, state, options);\n        },
                                  "name": "arity",
                                  "arg": 4
                                }
                              ],
                              "_refs": [],
                              "_flags": {
                                "func": true
                              },
                              "_description": null,
                              "_unit": null,
                              "_notes": [],
                              "_tags": [],
                              "_examples": [],
                              "_meta": [],
                              "_inner": {
                                "children": null,
                                "renames": [],
                                "dependencies": [],
                                "patterns": []
                              }
                            }
                          },
                          {
                            "key": "params",
                            "schema": {
                              "isJoi": true,
                              "_currentJoi": "[Circular ~.base._currentJoi]",
                              "_type": "alternatives",
                              "_settings": null,
                              "_valids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_invalids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_tests": [],
                              "_refs": [],
                              "_flags": {},
                              "_description": null,
                              "_unit": null,
                              "_notes": [],
                              "_tags": [],
                              "_examples": [],
                              "_meta": [],
                              "_inner": {
                                "matches": [
                                  {
                                    "schema": {
                                      "isJoi": true,
                                      "_currentJoi": "[Circular ~.base._currentJoi]",
                                      "_type": "object",
                                      "_settings": null,
                                      "_valids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_invalids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_tests": [],
                                      "_refs": [],
                                      "_flags": {},
                                      "_description": null,
                                      "_unit": null,
                                      "_notes": [],
                                      "_tags": [],
                                      "_examples": [],
                                      "_meta": [],
                                      "_inner": {
                                        "children": null,
                                        "renames": [],
                                        "dependencies": [],
                                        "patterns": [
                                          {
                                            "regex": {},
                                            "rule": {
                                              "isJoi": true,
                                              "_currentJoi": "[Circular ~.base._currentJoi]",
                                              "_type": "object",
                                              "_settings": null,
                                              "_valids": {
                                                "_set": {},
                                                "_hasRef": false
                                              },
                                              "_invalids": {
                                                "_set": {},
                                                "_hasRef": false
                                              },
                                              "_tests": [
                                                {
                                                  "func": function (value, state, options) {\n\n            if (value instanceof constructor) {\n                return value;\n            }\n\n            return this.createError('object.type', { type: typeData.name, value }, state, options);\n        },
                                                  "name": "type",
                                                  "arg": {
                                                    "name": "Joi object",
                                                    "ctor": "[class {\n\n    constructor() {\n\n        this.isJoi = true;\n        this._type = 'any';\n        this._settings = null;\n        this._valids = new internals.Set();\n        this._invalids = new internals.Set();\n        this._tests = [];\n        this._refs = [];\n        this._flags = {\n            /*\n             presence: 'optional',                   // optional, required, forbidden, ignore\n             allowOnly: false,\n             allowUnknown: undefined,\n             default: undefined,\n             forbidden: false,\n             encoding: undefined,\n             insensitive: false,\n             trim: false,\n             normalize: undefined,                   // NFC, NFD, NFKC, NFKD\n             case: undefined,                        // upper, lower\n             empty: undefined,\n             func: false,\n             raw: false\n             */\n        };\n\n        this._description = null;\n        this._unit = null;\n        this._notes = [];\n        this._tags = [];\n        this._examples = [];\n        this._meta = [];\n\n        this._inner = {};                           // Hash of arrays of immutable objects\n    }\n\n    _init() {\n\n        return this;\n    }\n\n    get schemaType() {\n\n        return this._type;\n    }\n\n    createError(type, context, state, options, flags = this._flags) {\n\n        return Errors.create(type, context, state, options, flags);\n    }\n\n    createOverrideError(type, context, state, options, message, template) {\n\n        return Errors.create(type, context, state, options, this._flags, message, template);\n    }\n\n    checkOptions(options) {\n\n        Schemas = Schemas || require('../../schemas');\n\n        const result = Schemas.options.validate(options);\n\n        if (result.error) {\n            throw new Error(result.error.details[0].message);\n        }\n    }\n\n    clone() {\n\n        const obj = Object.create(Object.getPrototypeOf(this));\n\n        obj.isJoi = true;\n        obj._currentJoi = this._currentJoi;\n        obj._type = this._type;\n        obj._settings = this._settings;\n        obj._baseType = this._baseType;\n        obj._valids = this._valids.slice();\n        obj._invalids = this._invalids.slice();\n        obj._tests = this._tests.slice();\n        obj._refs = this._refs.slice();\n        obj._flags = Hoek.clone(this._flags);\n\n        obj._description = this._description;\n        obj._unit = this._unit;\n        obj._notes = this._notes.slice();\n        obj._tags = this._tags.slice();\n        obj._examples = this._examples.slice();\n        obj._meta = this._meta.slice();\n\n        obj._inner = {};\n        const inners = Object.keys(this._inner);\n        for (let i = 0; i < inners.length; ++i) {\n            const key = inners[i];\n            obj._inner[key] = this._inner[key] ? this._inner[key].slice() : null;\n        }\n\n        return obj;\n    }\n\n    concat(schema) {\n\n        Hoek.assert(schema instanceof internals.Any, 'Invalid schema object');\n        Hoek.assert(this._type === 'any' || schema._type === 'any' || schema._type === this._type, 'Cannot merge type', this._type, 'with another type:', schema._type);\n\n        let obj = this.clone();\n\n        if (this._type === 'any' && schema._type !== 'any') {\n\n            // Reset values as if we were \"this\"\n            const tmpObj = schema.clone();\n            const keysToRestore = ['_settings', '_valids', '_invalids', '_tests', '_refs', '_flags', '_description', '_unit',\n                '_notes', '_tags', '_examples', '_meta', '_inner'];\n\n            for (let i = 0; i < keysToRestore.length; ++i) {\n                tmpObj[keysToRestore[i]] = obj[keysToRestore[i]];\n            }\n\n            obj = tmpObj;\n        }\n\n        obj._settings = obj._settings ? Settings.concat(obj._settings, schema._settings) : schema._settings;\n        obj._valids.merge(schema._valids, schema._invalids);\n        obj._invalids.merge(schema._invalids, schema._valids);\n        obj._tests.push(...schema._tests);\n        obj._refs.push(...schema._refs);\n        if (obj._flags.empty && schema._flags.empty) {\n            obj._flags.empty = obj._flags.empty.concat(schema._flags.empty);\n            const flags = Object.assign({}, schema._flags);\n            delete flags.empty;\n            Hoek.merge(obj._flags, flags);\n        }\n        else if (schema._flags.empty) {\n            obj._flags.empty = schema._flags.empty;\n            const flags = Object.assign({}, schema._flags);\n            delete flags.empty;\n            Hoek.merge(obj._flags, flags);\n        }\n        else {\n            Hoek.merge(obj._flags, schema._flags);\n        }\n\n        obj._description = schema._description || obj._description;\n        obj._unit = schema._unit || obj._unit;\n        obj._notes.push(...schema._notes);\n        obj._tags.push(...schema._tags);\n        obj._examples.push(...schema._examples);\n        obj._meta.push(...schema._meta);\n\n        const inners = Object.keys(schema._inner);\n        const isObject = obj._type === 'object';\n        for (let i = 0; i < inners.length; ++i) {\n            const key = inners[i];\n            const source = schema._inner[key];\n            if (source) {\n                const target = obj._inner[key];\n                if (target) {\n                    if (isObject && key === 'children') {\n                        const keys = {};\n\n                        for (let j = 0; j < target.length; ++j) {\n                            keys[target[j].key] = j;\n                        }\n\n                        for (let j = 0; j < source.length; ++j) {\n                            const sourceKey = source[j].key;\n                            if (keys[sourceKey] >= 0) {\n                                target[keys[sourceKey]] = {\n                                    key: sourceKey,\n                                    schema: target[keys[sourceKey]].schema.concat(source[j].schema)\n                                };\n                            }\n                            else {\n                                target.push(source[j]);\n                            }\n                        }\n                    }\n                    else {\n                        obj._inner[key] = obj._inner[key].concat(source);\n                    }\n                }\n                else {\n                    obj._inner[key] = source.slice();\n                }\n            }\n        }\n\n        return obj;\n    }\n\n    _test(name, arg, func, options) {\n\n        const obj = this.clone();\n        obj._tests.push({ func, name, arg, options });\n        return obj;\n    }\n\n    _testUnique(name, arg, func, options) {\n\n        const obj = this.clone();\n        obj._tests = obj._tests.filter((test) => test.name !== name);\n        obj._tests.push({ func, name, arg, options });\n        return obj;\n    }\n\n    options(options) {\n\n        Hoek.assert(!options.context, 'Cannot override context');\n        this.checkOptions(options);\n\n        const obj = this.clone();\n        obj._settings = Settings.concat(obj._settings, options);\n        return obj;\n    }\n\n    strict(isStrict) {\n\n        const obj = this.clone();\n\n        const convert = isStrict === undefined ? false : !isStrict;\n        obj._settings = Settings.concat(obj._settings, { convert });\n        return obj;\n    }\n\n    raw(isRaw) {\n\n        const value = isRaw === undefined ? true : isRaw;\n\n        if (this._flags.raw === value) {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.raw = value;\n        return obj;\n    }\n\n    error(err, options = { self: false }) {\n\n        Hoek.assert(err && (err instanceof Error || typeof err === 'function'), 'Must provide a valid Error object or a function');\n\n        const unknownKeys = Object.keys(options).filter((k) => !['self'].includes(k));\n        Hoek.assert(unknownKeys.length === 0, `Options ${unknownKeys} are unknown`);\n\n        const obj = this.clone();\n        obj._flags.error = err;\n\n        if (options.self) {\n            obj._flags.selfError = true;\n        }\n\n        return obj;\n    }\n\n    allow(...values) {\n\n        const obj = this.clone();\n        values = Hoek.flatten(values);\n        for (let i = 0; i < values.length; ++i) {\n            const value = values[i];\n\n            Hoek.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');\n            obj._invalids.remove(value);\n            obj._valids.add(value, obj._refs);\n        }\n\n        return obj;\n    }\n\n    valid(...values) {\n\n        const obj = this.allow(...values);\n        obj._flags.allowOnly = true;\n        return obj;\n    }\n\n    invalid(...values) {\n\n        const obj = this.clone();\n        values = Hoek.flatten(values);\n        for (let i = 0; i < values.length; ++i) {\n            const value = values[i];\n\n            Hoek.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');\n            obj._valids.remove(value);\n            obj._invalids.add(value, obj._refs);\n        }\n\n        return obj;\n    }\n\n    required() {\n\n        if (this._flags.presence === 'required') {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.presence = 'required';\n        return obj;\n    }\n\n    optional() {\n\n        if (this._flags.presence === 'optional') {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.presence = 'optional';\n        return obj;\n    }\n\n\n    forbidden() {\n\n        if (this._flags.presence === 'forbidden') {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.presence = 'forbidden';\n        return obj;\n    }\n\n\n    strip() {\n\n        if (this._flags.strip) {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.strip = true;\n        return obj;\n    }\n\n    applyFunctionToChildren(children, fn, args = [], root) {\n\n        children = [].concat(children);\n\n        if (children.length !== 1 || children[0] !== '') {\n            root = root ? (root + '.') : '';\n\n            const extraChildren = (children[0] === '' ? children.slice(1) : children).map((child) => {\n\n                return root + child;\n            });\n\n            throw new Error('unknown key(s) ' + extraChildren.join(', '));\n        }\n\n        return this[fn](...args);\n    }\n\n    default(value, description) {\n\n        if (typeof value === 'function' &&\n            !Ref.isRef(value)) {\n\n            if (!value.description &&\n                description) {\n\n                value.description = description;\n            }\n\n            if (!this._flags.func) {\n                Hoek.assert(typeof value.description === 'string' && value.description.length > 0, 'description must be provided when default value is a function');\n            }\n        }\n\n        const obj = this.clone();\n        obj._flags.default = value;\n        Ref.push(obj._refs, value);\n        return obj;\n    }\n\n    empty(schema) {\n\n        const obj = this.clone();\n        if (schema === undefined) {\n            delete obj._flags.empty;\n        }\n        else {\n            obj._flags.empty = Cast.schema(this._currentJoi, schema);\n        }\n\n        return obj;\n    }\n\n    when(condition, options) {\n\n        Hoek.assert(options && typeof options === 'object', 'Invalid options');\n        Hoek.assert(options.then !== undefined || options.otherwise !== undefined, 'options must have at least one of \"then\" or \"otherwise\"');\n\n        const then = options.hasOwnProperty('then') ? this.concat(Cast.schema(this._currentJoi, options.then)) : undefined;\n        const otherwise = options.hasOwnProperty('otherwise') ? this.concat(Cast.schema(this._currentJoi, options.otherwise)) : undefined;\n\n        Alternatives = Alternatives || require('../alternatives');\n\n        const alternativeOptions = { then, otherwise };\n        if (Object.prototype.hasOwnProperty.call(options, 'is')) {\n            alternativeOptions.is = options.is;\n        }\n\n        const obj = Alternatives.when(condition, alternativeOptions);\n        obj._flags.presence = 'ignore';\n        obj._baseType = this;\n\n        return obj;\n    }\n\n    description(desc) {\n\n        Hoek.assert(desc && typeof desc === 'string', 'Description must be a non-empty string');\n\n        const obj = this.clone();\n        obj._description = desc;\n        return obj;\n    }\n\n    notes(notes) {\n\n        Hoek.assert(notes && (typeof notes === 'string' || Array.isArray(notes)), 'Notes must be a non-empty string or array');\n\n        const obj = this.clone();\n        obj._notes = obj._notes.concat(notes);\n        return obj;\n    }\n\n    tags(tags) {\n\n        Hoek.assert(tags && (typeof tags === 'string' || Array.isArray(tags)), 'Tags must be a non-empty string or array');\n\n        const obj = this.clone();\n        obj._tags = obj._tags.concat(tags);\n        return obj;\n    }\n\n    meta(meta) {\n\n        Hoek.assert(meta !== undefined, 'Meta cannot be undefined');\n\n        const obj = this.clone();\n        obj._meta = obj._meta.concat(meta);\n        return obj;\n    }\n\n    example(...examples) {\n\n        Hoek.assert(examples.length > 0, 'Missing examples');\n\n        const processed = [];\n        for (let i = 0; i < examples.length; ++i) {\n            const example = [].concat(examples[i]);\n            Hoek.assert(example.length <= 2, `Bad example format at index ${i}`);\n\n            const value = example[0];\n            let options = example[1];\n            if (options !== undefined) {\n                Hoek.assert(options && typeof options === 'object', `Options for example at index ${i} must be an object`);\n                const unknownOptions = Object.keys(options).filter((option) => !['parent', 'context'].includes(option));\n                Hoek.assert(unknownOptions.length === 0, `Unknown example options ${unknownOptions} at index ${i}`);\n            }\n            else {\n                options = {};\n            }\n\n            const localState = new State('', [], options.parent || null);\n            const result = this._validate(value, localState, Settings.concat(internals.defaults, options.context ? { context: options.context } : null));\n            Hoek.assert(!result.errors, `Bad example at index ${i}:`, result.errors && Errors.process(result.errors, value));\n\n            const ex = { value };\n            if (Object.keys(options).length) {\n                ex.options = options;\n            }\n\n            processed.push(ex);\n        }\n\n        const obj = this.clone();\n        obj._examples = processed;\n        return obj;\n    }\n\n    unit(name) {\n\n        Hoek.assert(name && typeof name === 'string', 'Unit name must be a non-empty string');\n\n        const obj = this.clone();\n        obj._unit = name;\n        return obj;\n    }\n\n    _prepareEmptyValue(value) {\n\n        if (typeof value === 'string' && this._flags.trim) {\n            return value.trim();\n        }\n\n        return value;\n    }\n\n    _validate(value, state, options, reference) {\n\n        const originalValue = value;\n\n        // Setup state and settings\n\n        state = state || new State('', [], null, reference);\n\n        if (this._settings) {\n            const isDefaultOptions = options === internals.defaults;\n            if (isDefaultOptions && this._settings[Symbols.settingsCache]) {\n                options = this._settings[Symbols.settingsCache];\n            }\n            else {\n                options = Settings.concat(this._language ? Settings.concat({ language: this._language }, options) : options, this._settings);\n                if (isDefaultOptions) {\n                    this._settings[Symbols.settingsCache] = options;\n                }\n            }\n        }\n        else if (this._language) {\n            options = Settings.concat({ language: this._language }, options);\n        }\n\n        let errors = [];\n\n        if (this._coerce) {\n            const coerced = this._coerce(value, state, options);\n            if (coerced.errors) {\n                value = coerced.value;\n                errors = errors.concat(coerced.errors);\n                return this._finalizeValue(value, originalValue, errors, state, options);                            // Coerced error always aborts early\n            }\n\n            value = coerced.value;\n        }\n\n        if (this._flags.empty && !this._flags.empty._validate(this._prepareEmptyValue(value), null, internals.defaults).errors) {\n            value = undefined;\n        }\n\n        // Check presence requirements\n\n        const presence = this._flags.presence || options.presence;\n        if (presence === 'optional') {\n            if (value === undefined) {\n                const isDeepDefault = this._flags.hasOwnProperty('default') && this._flags.default === undefined;\n                if (isDeepDefault && this._type === 'object') {\n                    value = {};\n                }\n                else {\n                    return this._finalizeValue(value, originalValue, errors, state, options);\n                }\n            }\n        }\n        else if (presence === 'required' &&\n            value === undefined) {\n\n            errors.push(this.createError('any.required', null, state, options));\n            return this._finalizeValue(value, originalValue, errors, state, options);\n        }\n        else if (presence === 'forbidden') {\n            if (value === undefined) {\n                return this._finalizeValue(value, originalValue, errors, state, options);\n            }\n\n            errors.push(this.createError('any.unknown', null, state, options));\n            return this._finalizeValue(value, originalValue, errors, state, options);\n        }\n\n        // Check allowed and denied values using the original value\n\n        let match = this._valids.get(value, state, options, this._flags.insensitive);\n        if (match) {\n            if (options.convert) {\n                value = match.value;\n            }\n\n            return this._finalizeValue(value, originalValue, errors, state, options);\n        }\n\n        if (this._invalids.has(value, state, options, this._flags.insensitive)) {\n            errors.push(this.createError(value === '' ? 'any.empty' : 'any.invalid', { value, invalids: this._invalids.values({ stripUndefined: true }) }, state, options));\n            if (options.abortEarly) {\n\n                return this._finalizeValue(value, originalValue, errors, state, options);\n            }\n        }\n\n        // Convert value and validate type\n\n        if (this._base) {\n            const base = this._base(value, state, options);\n            if (base.errors) {\n                value = base.value;\n                errors = errors.concat(base.errors);\n                return this._finalizeValue(value, originalValue, errors, state, options);                            // Base error always aborts early\n            }\n\n            if (base.value !== value) {\n                value = base.value;\n\n                // Check allowed and denied values using the converted value\n\n                match = this._valids.get(value, state, options, this._flags.insensitive);\n                if (match) {\n                    value = match.value;\n                    return this._finalizeValue(value, originalValue, errors, state, options);\n                }\n\n                if (this._invalids.has(value, state, options, this._flags.insensitive)) {\n                    errors.push(this.createError(value === '' ? 'any.empty' : 'any.invalid', { value, invalids: this._invalids.values({ stripUndefined: true }) }, state, options));\n                    if (options.abortEarly) {\n                        return this._finalizeValue(value, originalValue, errors, state, options);\n                    }\n                }\n            }\n        }\n\n        // Required values did not match\n\n        if (this._flags.allowOnly) {\n            errors.push(this.createError('any.allowOnly', { value, valids: this._valids.values({ stripUndefined: true }) }, state, options));\n            if (options.abortEarly) {\n                return this._finalizeValue(value, originalValue, errors, state, options);\n            }\n        }\n\n        // Validate tests\n\n        for (let i = 0; i < this._tests.length; ++i) {\n            const test = this._tests[i];\n            const ret = test.func.call(this, value, state, options);\n            if (ret instanceof Errors.Err) {\n                errors.push(ret);\n                if (options.abortEarly) {\n                    return this._finalizeValue(value, originalValue, errors, state, options);\n                }\n            }\n            else {\n                value = ret;\n            }\n        }\n\n        return this._finalizeValue(value, originalValue, errors, state, options);\n    }\n\n    _finalizeValue(value, originalValue, errors, state, options) {\n\n        let finalValue;\n\n        if (value !== undefined) {\n            finalValue = this._flags.raw ? originalValue : value;\n        }\n        else if (options.noDefaults) {\n            finalValue = value;\n        }\n        else if (Ref.isRef(this._flags.default)) {\n            finalValue = this._flags.default(state.parent, options);\n        }\n        else if (typeof this._flags.default === 'function' &&\n            !(this._flags.func && !this._flags.default.description)) {\n\n            let args;\n\n            if (state.parent !== null &&\n                this._flags.default.length > 0) {\n\n                args = [Hoek.clone(state.parent), options];\n            }\n\n            const defaultValue = internals._try(this._flags.default, args);\n            finalValue = defaultValue.value;\n            if (defaultValue.error) {\n                errors.push(this.createError('any.default', { error: defaultValue.error }, state, options));\n            }\n        }\n        else {\n            finalValue = Hoek.clone(this._flags.default);\n        }\n\n        if (errors.length &&\n            typeof this._flags.error === 'function' &&\n            (\n                !this._flags.selfError ||\n                errors.some((e) => state.path.length === e.path.length)\n            )\n        ) {\n            const change = this._flags.error.call(this, errors);\n\n            if (typeof change === 'string') {\n                errors = [this.createOverrideError('override', { reason: errors }, state, options, change)];\n            }\n            else {\n                errors = [].concat(change)\n                    .map((err) => {\n\n                        return err instanceof Error ?\n                            err :\n                            this.createOverrideError(err.type || 'override', err.context, state, options, err.message, err.template);\n                    });\n            }\n        }\n\n        return {\n            value: this._flags.strip ? undefined : finalValue,\n            finalValue,\n            errors: errors.length ? errors : null\n        };\n    }\n\n    _validateWithOptions(value, options, callback) {\n\n        if (options) {\n            this.checkOptions(options);\n        }\n\n        const settings = Settings.concat(internals.defaults, options);\n        const result = this._validate(value, null, settings);\n        const errors = Errors.process(result.errors, value);\n\n        if (callback) {\n            return callback(errors, result.value);\n        }\n\n        return {\n            error: errors,\n            value: result.value,\n            then(resolve, reject) {\n\n                if (errors) {\n                    return Promise.reject(errors).catch(reject);\n                }\n\n                return Promise.resolve(result.value).then(resolve);\n            },\n            catch(reject) {\n\n                if (errors) {\n                    return Promise.reject(errors).catch(reject);\n                }\n\n                return Promise.resolve(result.value);\n            }\n        };\n    }\n\n    validate(value, options, callback) {\n\n        if (typeof options === 'function') {\n            return this._validateWithOptions(value, null, options);\n        }\n\n        return this._validateWithOptions(value, options, callback);\n    }\n\n    describe() {\n\n        const description = {\n            type: this._type\n        };\n\n        const flags = Object.keys(this._flags);\n        if (flags.length) {\n            if (['empty', 'default', 'lazy', 'label'].some((flag) => this._flags.hasOwnProperty(flag))) {\n                description.flags = {};\n                for (let i = 0; i < flags.length; ++i) {\n                    const flag = flags[i];\n                    if (flag === 'empty') {\n                        description.flags[flag] = this._flags[flag].describe();\n                    }\n                    else if (flag === 'default') {\n                        if (Ref.isRef(this._flags[flag])) {\n                            description.flags[flag] = this._flags[flag].toString();\n                        }\n                        else if (typeof this._flags[flag] === 'function') {\n                            description.flags[flag] = {\n                                description: this._flags[flag].description,\n                                function   : this._flags[flag]\n                            };\n                        }\n                        else {\n                            description.flags[flag] = this._flags[flag];\n                        }\n                    }\n                    else if (flag === 'lazy' || flag === 'label') {\n                        // We don't want it in the description\n                    }\n                    else {\n                        description.flags[flag] = this._flags[flag];\n                    }\n                }\n            }\n            else {\n                description.flags = this._flags;\n            }\n        }\n\n        if (this._settings) {\n            description.options = Hoek.clone(this._settings);\n        }\n\n        if (this._baseType) {\n            description.base = this._baseType.describe();\n        }\n\n        if (this._description) {\n            description.description = this._description;\n        }\n\n        if (this._notes.length) {\n            description.notes = this._notes;\n        }\n\n        if (this._tags.length) {\n            description.tags = this._tags;\n        }\n\n        if (this._meta.length) {\n            description.meta = this._meta;\n        }\n\n        if (this._examples.length) {\n            description.examples = this._examples;\n        }\n\n        if (this._unit) {\n            description.unit = this._unit;\n        }\n\n        const valids = this._valids.values();\n        if (valids.length) {\n            description.valids = valids.map((v) => {\n\n                return Ref.isRef(v) ? v.toString() : v;\n            });\n        }\n\n        const invalids = this._invalids.values();\n        if (invalids.length) {\n            description.invalids = invalids.map((v) => {\n\n                return Ref.isRef(v) ? v.toString() : v;\n            });\n        }\n\n        description.rules = [];\n\n        for (let i = 0; i < this._tests.length; ++i) {\n            const validator = this._tests[i];\n            const item = { name: validator.name };\n\n            if (validator.arg !== void 0) {\n                item.arg = Ref.isRef(validator.arg) ? validator.arg.toString() : validator.arg;\n            }\n\n            const options = validator.options;\n            if (options) {\n                if (options.hasRef) {\n                    item.arg = {};\n                    const keys = Object.keys(validator.arg);\n                    for (let j = 0; j < keys.length; ++j) {\n                        const key = keys[j];\n                        const value = validator.arg[key];\n                        item.arg[key] = Ref.isRef(value) ? value.toString() : value;\n                    }\n                }\n\n                if (typeof options.description === 'string') {\n                    item.description = options.description;\n                }\n                else if (typeof options.description === 'function') {\n                    item.description = options.description(item.arg);\n                }\n            }\n\n            description.rules.push(item);\n        }\n\n        if (!description.rules.length) {\n            delete description.rules;\n        }\n\n        const label = this._getLabel();\n        if (label) {\n            description.label = label;\n        }\n\n        return description;\n    }\n\n    label(name) {\n\n        Hoek.assert(name && typeof name === 'string', 'Label name must be a non-empty string');\n\n        const obj = this.clone();\n        obj._flags.label = name;\n        return obj;\n    }\n\n    _getLabel(def) {\n\n        return this._flags.label || def;\n    }\n\n}]"
                                                  }
                                                }
                                              ],
                                              "_refs": [],
                                              "_flags": {},
                                              "_description": null,
                                              "_unit": null,
                                              "_notes": [],
                                              "_tags": [],
                                              "_examples": [],
                                              "_meta": [],
                                              "_inner": {
                                                "children": null,
                                                "renames": [],
                                                "dependencies": [],
                                                "patterns": []
                                              }
                                            }
                                          }
                                        ]
                                      }
                                    }
                                  },
                                  {
                                    "schema": {
                                      "isJoi": true,
                                      "_currentJoi": "[Circular ~.base._currentJoi]",
                                      "_type": "object",
                                      "_settings": null,
                                      "_valids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_invalids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_tests": [
                                        {
                                          "func": function (value, state, options) {\n\n            if (value instanceof constructor) {\n                return value;\n            }\n\n            return this.createError('object.type', { type: typeData.name, value }, state, options);\n        },
                                          "name": "type",
                                          "arg": {
                                            "name": "Joi object",
                                            "ctor": "[class extends Any {\n\n    constructor() {\n\n        super();\n        this._type = 'object';\n        this._inner.children = null;\n        this._inner.renames = [];\n        this._inner.dependencies = [];\n        this._inner.patterns = [];\n    }\n\n    _init(...args) {\n\n        return args.length ? this.keys(...args) : this;\n    }\n\n    _base(value, state, options) {\n\n        let target = value;\n        const errors = [];\n        const finish = () => {\n\n            return {\n                value: target,\n                errors: errors.length ? errors : null\n            };\n        };\n\n        if (typeof value === 'string' &&\n            options.convert) {\n\n            if (value.length > 1 &&\n                (value[0] === '{' || /^\\s*\\{/.test(value))) {\n\n                try {\n                    value = Bourne.parse(value);\n                }\n                catch (e) { }\n            }\n        }\n\n        const type = this._flags.func ? 'function' : 'object';\n        if (!value ||\n            typeof value !== type ||\n            Array.isArray(value)) {\n\n            errors.push(this.createError(type + '.base', { value }, state, options));\n            return finish();\n        }\n\n        // Skip if there are no other rules to test\n\n        if (!this._inner.renames.length &&\n            !this._inner.dependencies.length &&\n            !this._inner.children &&                    // null allows any keys\n            !this._inner.patterns.length) {\n\n            target = value;\n            return finish();\n        }\n\n        // Ensure target is a local copy (parsed) or shallow copy\n\n        if (target === value) {\n            if (type === 'object') {\n                target = Object.create(Object.getPrototypeOf(value));\n            }\n            else {\n                target = function (...args) {\n\n                    return value.apply(this, args);\n                };\n\n                target.prototype = Hoek.clone(value.prototype);\n            }\n\n            const valueKeys = Object.keys(value);\n            for (let i = 0; i < valueKeys.length; ++i) {\n                target[valueKeys[i]] = value[valueKeys[i]];\n            }\n        }\n        else {\n            target = value;\n        }\n\n        // Rename keys\n\n        const renamed = {};\n        for (let i = 0; i < this._inner.renames.length; ++i) {\n            const rename = this._inner.renames[i];\n\n            if (rename.isRegExp) {\n                const targetKeys = Object.keys(target);\n                const matchedTargetKeys = [];\n\n                for (let j = 0; j < targetKeys.length; ++j) {\n                    if (rename.from.test(targetKeys[j])) {\n                        matchedTargetKeys.push(targetKeys[j]);\n                    }\n                }\n\n                const allUndefined = matchedTargetKeys.every((key) => target[key] === undefined);\n                if (rename.options.ignoreUndefined && allUndefined) {\n                    continue;\n                }\n\n                if (!rename.options.multiple &&\n                    renamed[rename.to]) {\n\n                    errors.push(this.createError('object.rename.regex.multiple', { from: matchedTargetKeys, to: rename.to }, state, options));\n                    if (options.abortEarly) {\n                        return finish();\n                    }\n                }\n\n                if (Object.prototype.hasOwnProperty.call(target, rename.to) &&\n                    !rename.options.override &&\n                    !renamed[rename.to]) {\n\n                    errors.push(this.createError('object.rename.regex.override', { from: matchedTargetKeys, to: rename.to }, state, options));\n                    if (options.abortEarly) {\n                        return finish();\n                    }\n                }\n\n                if (allUndefined) {\n                    delete target[rename.to];\n                }\n                else {\n                    target[rename.to] = target[matchedTargetKeys[matchedTargetKeys.length - 1]];\n                }\n\n                renamed[rename.to] = true;\n\n                if (!rename.options.alias) {\n                    for (let j = 0; j < matchedTargetKeys.length; ++j) {\n                        delete target[matchedTargetKeys[j]];\n                    }\n                }\n            }\n            else {\n                if (rename.options.ignoreUndefined && target[rename.from] === undefined) {\n                    continue;\n                }\n\n                if (!rename.options.multiple &&\n                    renamed[rename.to]) {\n\n                    errors.push(this.createError('object.rename.multiple', { from: rename.from, to: rename.to }, state, options));\n                    if (options.abortEarly) {\n                        return finish();\n                    }\n                }\n\n                if (Object.prototype.hasOwnProperty.call(target, rename.to) &&\n                    !rename.options.override &&\n                    !renamed[rename.to]) {\n\n                    errors.push(this.createError('object.rename.override', { from: rename.from, to: rename.to }, state, options));\n                    if (options.abortEarly) {\n                        return finish();\n                    }\n                }\n\n                if (target[rename.from] === undefined) {\n                    delete target[rename.to];\n                }\n                else {\n                    target[rename.to] = target[rename.from];\n                }\n\n                renamed[rename.to] = true;\n\n                if (!rename.options.alias) {\n                    delete target[rename.from];\n                }\n            }\n        }\n\n        // Validate schema\n\n        if (!this._inner.children &&            // null allows any keys\n            !this._inner.patterns.length &&\n            !this._inner.dependencies.length) {\n\n            return finish();\n        }\n\n        const unprocessed = new Set(Object.keys(target));\n\n        if (this._inner.children) {\n            const stripProps = [];\n\n            for (let i = 0; i < this._inner.children.length; ++i) {\n                const child = this._inner.children[i];\n                const key = child.key;\n                const item = target[key];\n\n                unprocessed.delete(key);\n\n                const localState = new State(key, [...state.path, key], target, state.reference);\n                const result = child.schema._validate(item, localState, options);\n                if (result.errors) {\n                    errors.push(this.createError('object.child', { key, child: child.schema._getLabel(key), reason: result.errors }, localState, options));\n\n                    if (options.abortEarly) {\n                        return finish();\n                    }\n                }\n                else {\n                    if (child.schema._flags.strip || (result.value === undefined && result.value !== item)) {\n                        stripProps.push(key);\n                        target[key] = result.finalValue;\n                    }\n                    else if (result.value !== undefined) {\n                        target[key] = result.value;\n                    }\n                }\n            }\n\n            for (let i = 0; i < stripProps.length; ++i) {\n                delete target[stripProps[i]];\n            }\n        }\n\n        // Unknown keys\n\n        if (unprocessed.size && this._inner.patterns.length) {\n\n            for (const key of unprocessed) {\n                const localState = new State(key, [...state.path, key], target, state.reference);\n                const item = target[key];\n\n                for (let i = 0; i < this._inner.patterns.length; ++i) {\n                    const pattern = this._inner.patterns[i];\n\n                    if (pattern.regex ?\n                        pattern.regex.test(key) :\n                        !pattern.schema._validate(key, state, { ...options, abortEarly:true }).errors) {\n\n                        unprocessed.delete(key);\n\n                        const result = pattern.rule._validate(item, localState, options);\n                        if (result.errors) {\n                            errors.push(this.createError('object.child', {\n                                key,\n                                child: pattern.rule._getLabel(key),\n                                reason: result.errors\n                            }, localState, options));\n\n                            if (options.abortEarly) {\n                                return finish();\n                            }\n                        }\n\n                        target[key] = result.value;\n                    }\n                }\n            }\n        }\n\n        if (unprocessed.size && (this._inner.children || this._inner.patterns.length)) {\n            if ((options.stripUnknown && this._flags.allowUnknown !== true) ||\n                options.skipFunctions) {\n\n                const stripUnknown = options.stripUnknown\n                    ? (options.stripUnknown === true ? true : !!options.stripUnknown.objects)\n                    : false;\n\n\n                for (const key of unprocessed) {\n                    if (stripUnknown) {\n                        delete target[key];\n                        unprocessed.delete(key);\n                    }\n                    else if (typeof target[key] === 'function') {\n                        unprocessed.delete(key);\n                    }\n                }\n            }\n\n            if ((this._flags.allowUnknown !== undefined ? !this._flags.allowUnknown : !options.allowUnknown)) {\n\n                for (const unprocessedKey of unprocessed) {\n                    errors.push(this.createError('object.allowUnknown', { child: unprocessedKey, value: target[unprocessedKey] }, {\n                        key: unprocessedKey,\n                        path: [...state.path, unprocessedKey]\n                    }, options, {}));\n                }\n            }\n        }\n\n        // Validate dependencies\n\n        for (let i = 0; i < this._inner.dependencies.length; ++i) {\n            const dep = this._inner.dependencies[i];\n            const hasKey = dep.key !== null;\n            const splitKey = hasKey && dep.key.split('.');\n            const localState = hasKey ? new State(splitKey[splitKey.length - 1], [...state.path, ...splitKey]) : new State(null, state.path);\n            const err = internals[dep.type].call(this, dep.key, hasKey && Hoek.reach(target, dep.key, { functions: true }), dep.peers, target, localState, options);\n            if (err instanceof Errors.Err) {\n                errors.push(err);\n                if (options.abortEarly) {\n                    return finish();\n                }\n            }\n        }\n\n        return finish();\n    }\n\n    keys(schema) {\n\n        Hoek.assert(schema === null || schema === undefined || typeof schema === 'object', 'Object schema must be a valid object');\n        Hoek.assert(!schema || !(schema instanceof Any), 'Object schema cannot be a joi schema');\n\n        const obj = this.clone();\n\n        if (!schema) {\n            obj._inner.children = null;\n            return obj;\n        }\n\n        const children = Object.keys(schema);\n\n        if (!children.length) {\n            obj._inner.children = [];\n            return obj;\n        }\n\n        const topo = new Topo();\n        if (obj._inner.children) {\n            for (let i = 0; i < obj._inner.children.length; ++i) {\n                const child = obj._inner.children[i];\n\n                // Only add the key if we are not going to replace it later\n                if (!children.includes(child.key)) {\n                    topo.add(child, { after: child._refs, group: child.key });\n                }\n            }\n        }\n\n        for (let i = 0; i < children.length; ++i) {\n            const key = children[i];\n            const child = schema[key];\n            try {\n                const cast = Cast.schema(this._currentJoi, child);\n                topo.add({ key, schema: cast }, { after: cast._refs, group: key });\n            }\n            catch (castErr) {\n                if (castErr.hasOwnProperty('path')) {\n                    castErr.path = key + '.' + castErr.path;\n                }\n                else {\n                    castErr.path = key;\n                }\n\n                throw castErr;\n            }\n        }\n\n        obj._inner.children = topo.nodes;\n\n        return obj;\n    }\n\n    append(schema) {\n        // Skip any changes\n        if (schema === null || schema === undefined || Object.keys(schema).length === 0) {\n            return this;\n        }\n\n        return this.keys(schema);\n    }\n\n    unknown(allow) {\n\n        const value = allow !== false;\n\n        if (this._flags.allowUnknown === value) {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.allowUnknown = value;\n        return obj;\n    }\n\n    length(limit) {\n\n        Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');\n\n        return this._test('length', limit, function (value, state, options) {\n\n            if (Object.keys(value).length === limit) {\n                return value;\n            }\n\n            return this.createError('object.length', { limit, value }, state, options);\n        });\n    }\n\n    min(limit) {\n\n        Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');\n\n        return this._test('min', limit, function (value, state, options) {\n\n            if (Object.keys(value).length >= limit) {\n                return value;\n            }\n\n            return this.createError('object.min', { limit, value }, state, options);\n        });\n    }\n\n    max(limit) {\n\n        Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');\n\n        return this._test('max', limit, function (value, state, options) {\n\n            if (Object.keys(value).length <= limit) {\n                return value;\n            }\n\n            return this.createError('object.max', { limit, value }, state, options);\n        });\n    }\n\n    pattern(pattern, schema) {\n\n        const isRegExp = pattern instanceof RegExp;\n        Hoek.assert(isRegExp || pattern instanceof Any, 'pattern must be a regex or schema');\n        Hoek.assert(schema !== undefined, 'Invalid rule');\n\n        if (isRegExp) {\n            Hoek.assert(!pattern.flags.includes('g') && !pattern.flags.includes('y'), 'pattern should not use global or sticky mode');\n        }\n\n        try {\n            schema = Cast.schema(this._currentJoi, schema);\n        }\n        catch (castErr) {\n            if (castErr.hasOwnProperty('path')) {\n                castErr.message = `${castErr.message}(${castErr.path})`;\n            }\n\n            throw castErr;\n        }\n\n        const obj = this.clone();\n        if (isRegExp) {\n            obj._inner.patterns.push({ regex: pattern, rule: schema });\n        }\n        else {\n            obj._inner.patterns.push({ schema: pattern, rule: schema });\n        }\n\n        return obj;\n    }\n\n    schema() {\n\n        return this._test('schema', null, function (value, state, options) {\n\n            if (value instanceof Any) {\n                return value;\n            }\n\n            return this.createError('object.schema', null, state, options);\n        });\n    }\n\n    with(key, peers) {\n\n        Hoek.assert(arguments.length === 2, 'Invalid number of arguments, expected 2.');\n\n        return this._dependency('with', key, peers);\n    }\n\n    without(key, peers) {\n\n        Hoek.assert(arguments.length === 2, 'Invalid number of arguments, expected 2.');\n\n        return this._dependency('without', key, peers);\n    }\n\n    xor(...peers) {\n\n        peers = Hoek.flatten(peers);\n        return this._dependency('xor', null, peers);\n    }\n\n    oxor(...peers) {\n\n        return this._dependency('oxor', null, peers);\n    }\n\n    or(...peers) {\n\n        peers = Hoek.flatten(peers);\n        return this._dependency('or', null, peers);\n    }\n\n    and(...peers) {\n\n        peers = Hoek.flatten(peers);\n        return this._dependency('and', null, peers);\n    }\n\n    nand(...peers) {\n\n        peers = Hoek.flatten(peers);\n        return this._dependency('nand', null, peers);\n    }\n\n    requiredKeys(...children) {\n\n        children = Hoek.flatten(children);\n        return this.applyFunctionToChildren(children, 'required');\n    }\n\n    optionalKeys(...children) {\n\n        children = Hoek.flatten(children);\n        return this.applyFunctionToChildren(children, 'optional');\n    }\n\n    forbiddenKeys(...children) {\n\n        children = Hoek.flatten(children);\n        return this.applyFunctionToChildren(children, 'forbidden');\n    }\n\n    rename(from, to, options) {\n\n        Hoek.assert(typeof from === 'string' || from instanceof RegExp, 'Rename missing the from argument');\n        Hoek.assert(typeof to === 'string', 'Rename missing the to argument');\n        Hoek.assert(to !== from, 'Cannot rename key to same name:', from);\n\n        for (let i = 0; i < this._inner.renames.length; ++i) {\n            Hoek.assert(this._inner.renames[i].from !== from, 'Cannot rename the same key multiple times');\n        }\n\n        const obj = this.clone();\n\n        obj._inner.renames.push({\n            from,\n            to,\n            options: Hoek.applyToDefaults(internals.renameDefaults, options || {}),\n            isRegExp: from instanceof RegExp\n        });\n\n        return obj;\n    }\n\n    applyFunctionToChildren(children, fn, args = [], root) {\n\n        children = [].concat(children);\n        Hoek.assert(children.length > 0, 'expected at least one children');\n\n        const groupedChildren = internals.groupChildren(children);\n        let obj;\n\n        if ('' in groupedChildren) {\n            obj = this[fn](...args);\n            delete groupedChildren[''];\n        }\n        else {\n            obj = this.clone();\n        }\n\n        if (obj._inner.children) {\n            root = root ? (root + '.') : '';\n\n            for (let i = 0; i < obj._inner.children.length; ++i) {\n                const child = obj._inner.children[i];\n                const group = groupedChildren[child.key];\n\n                if (group) {\n                    obj._inner.children[i] = {\n                        key: child.key,\n                        _refs: child._refs,\n                        schema: child.schema.applyFunctionToChildren(group, fn, args, root + child.key)\n                    };\n\n                    delete groupedChildren[child.key];\n                }\n            }\n        }\n\n        const remaining = Object.keys(groupedChildren);\n        Hoek.assert(remaining.length === 0, 'unknown key(s)', remaining.join(', '));\n\n        return obj;\n    }\n\n    _dependency(type, key, peers) {\n\n        peers = [].concat(peers);\n        for (let i = 0; i < peers.length; ++i) {\n            Hoek.assert(typeof peers[i] === 'string', type, 'peers must be a string or array of strings');\n        }\n\n        const obj = this.clone();\n        obj._inner.dependencies.push({ type, key, peers });\n        return obj;\n    }\n\n    describe(shallow) {\n\n        const description = super.describe();\n\n        if (description.rules) {\n            for (let i = 0; i < description.rules.length; ++i) {\n                const rule = description.rules[i];\n                // Coverage off for future-proof descriptions, only object().assert() is use right now\n                if (/* $lab:coverage:off$ */rule.arg &&\n                    typeof rule.arg === 'object' &&\n                    rule.arg.schema &&\n                    rule.arg.ref /* $lab:coverage:on$ */) {\n                    rule.arg = {\n                        schema: rule.arg.schema.describe(),\n                        ref: rule.arg.ref.toString()\n                    };\n                }\n            }\n        }\n\n        if (this._inner.children &&\n            !shallow) {\n\n            description.children = {};\n            for (let i = 0; i < this._inner.children.length; ++i) {\n                const child = this._inner.children[i];\n                description.children[child.key] = child.schema.describe();\n            }\n        }\n\n        if (this._inner.dependencies.length) {\n            description.dependencies = Hoek.clone(this._inner.dependencies);\n        }\n\n        if (this._inner.patterns.length) {\n            description.patterns = [];\n\n            for (let i = 0; i < this._inner.patterns.length; ++i) {\n                const pattern = this._inner.patterns[i];\n                if (pattern.regex) {\n                    description.patterns.push({ regex: pattern.regex.toString(), rule: pattern.rule.describe() });\n                }\n                else {\n                    description.patterns.push({ schema: pattern.schema.describe(), rule: pattern.rule.describe() });\n                }\n            }\n        }\n\n        if (this._inner.renames.length > 0) {\n            description.renames = Hoek.clone(this._inner.renames);\n        }\n\n        return description;\n    }\n\n    assert(ref, schema, message) {\n\n        ref = Cast.ref(ref);\n        Hoek.assert(ref.isContext || ref.depth > 1, 'Cannot use assertions for root level references - use direct key rules instead');\n        message = message || 'pass the assertion test';\n        Hoek.assert(typeof message === 'string', 'Message must be a string');\n\n        try {\n            schema = Cast.schema(this._currentJoi, schema);\n        }\n        catch (castErr) {\n            if (castErr.hasOwnProperty('path')) {\n                castErr.message = `${castErr.message}(${castErr.path})`;\n            }\n\n            throw castErr;\n        }\n\n        const key = ref.path[ref.path.length - 1];\n        const path = ref.path.join('.');\n\n        return this._test('assert', { schema, ref }, function (value, state, options) {\n\n            const result = schema._validate(ref(value), null, options, value);\n            if (!result.errors) {\n                return value;\n            }\n\n            const localState = new State(key, ref.path, state.parent, state.reference);\n            return this.createError('object.assert', { ref: path, message }, localState, options);\n        });\n    }\n\n    type(constructor, name = constructor.name) {\n\n        Hoek.assert(typeof constructor === 'function', 'type must be a constructor function');\n        const typeData = {\n            name,\n            ctor: constructor\n        };\n\n        return this._test('type', typeData, function (value, state, options) {\n\n            if (value instanceof constructor) {\n                return value;\n            }\n\n            return this.createError('object.type', { type: typeData.name, value }, state, options);\n        });\n    }\n}]"
                                          }
                                        }
                                      ],
                                      "_refs": [],
                                      "_flags": {},
                                      "_description": null,
                                      "_unit": null,
                                      "_notes": [],
                                      "_tags": [],
                                      "_examples": [],
                                      "_meta": [],
                                      "_inner": {
                                        "children": null,
                                        "renames": [],
                                        "dependencies": [],
                                        "patterns": []
                                      }
                                    }
                                  }
                                ]
                              }
                            }
                          },
                          {
                            "key": "description",
                            "schema": {
                              "isJoi": true,
                              "_currentJoi": "[Circular ~.base._currentJoi]",
                              "_type": "alternatives",
                              "_settings": null,
                              "_valids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_invalids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_tests": [],
                              "_refs": [],
                              "_flags": {},
                              "_description": null,
                              "_unit": null,
                              "_notes": [],
                              "_tags": [],
                              "_examples": [],
                              "_meta": [],
                              "_inner": {
                                "matches": [
                                  {
                                    "schema": {
                                      "isJoi": true,
                                      "_type": "string",
                                      "_settings": null,
                                      "_valids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_invalids": {
                                        "_set": {},
                                        "_hasRef": 0
                                      },
                                      "_tests": [],
                                      "_refs": [],
                                      "_flags": {},
                                      "_description": null,
                                      "_unit": null,
                                      "_notes": [],
                                      "_tags": [],
                                      "_examples": [],
                                      "_meta": [],
                                      "_inner": {},
                                      "_currentJoi": "[Circular ~.base._currentJoi]"
                                    }
                                  },
                                  {
                                    "schema": {
                                      "isJoi": true,
                                      "_currentJoi": "[Circular ~.base._currentJoi]",
                                      "_type": "object",
                                      "_settings": null,
                                      "_valids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_invalids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_tests": [
                                        {
                                          "func": function (value, state, options) {\n\n            if (value.length === n) {\n                return value;\n            }\n\n            return this.createError('function.arity', { n }, state, options);\n        },
                                          "name": "arity",
                                          "arg": 1
                                        }
                                      ],
                                      "_refs": [],
                                      "_flags": {
                                        "func": true
                                      },
                                      "_description": null,
                                      "_unit": null,
                                      "_notes": [],
                                      "_tags": [],
                                      "_examples": [],
                                      "_meta": [],
                                      "_inner": {
                                        "children": null,
                                        "renames": [],
                                        "dependencies": [],
                                        "patterns": []
                                      }
                                    }
                                  }
                                ]
                              }
                            }
                          }
                        ],
                        "renames": [],
                        "dependencies": [
                          {
                            "type": "or",
                            "key": null,
                            "peers": [
                              "setup",
                              "validate"
                            ]
                          }
                        ],
                        "patterns": []
                      }
                    }
                  ],
                  "ordereds": [],
                  "inclusions": [
                    {
                      "isJoi": true,
                      "_currentJoi": "[Circular ~.base._currentJoi]",
                      "_type": "object",
                      "_settings": null,
                      "_valids": {
                        "_set": {},
                        "_hasRef": false
                      },
                      "_invalids": {
                        "_set": {},
                        "_hasRef": false
                      },
                      "_tests": [],
                      "_refs": [],
                      "_flags": {},
                      "_description": null,
                      "_unit": null,
                      "_notes": [],
                      "_tags": [],
                      "_examples": [],
                      "_meta": [],
                      "_inner": {
                        "children": [
                          {
                            "key": "name",
                            "schema": {
                              "isJoi": true,
                              "_currentJoi": "[Circular ~.base._currentJoi]",
                              "_type": "string",
                              "_settings": null,
                              "_valids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_invalids": {
                                "_set": {},
                                "_hasRef": 0
                              },
                              "_tests": [],
                              "_refs": [],
                              "_flags": {
                                "presence": "required"
                              },
                              "_description": null,
                              "_unit": null,
                              "_notes": [],
                              "_tags": [],
                              "_examples": [],
                              "_meta": [],
                              "_inner": {}
                            }
                          },
                          {
                            "key": "setup",
                            "schema": {
                              "isJoi": true,
                              "_currentJoi": "[Circular ~.base._currentJoi]",
                              "_type": "object",
                              "_settings": null,
                              "_valids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_invalids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_tests": [
                                {
                                  "func": function (value, state, options) {\n\n            if (value.length === n) {\n                return value;\n            }\n\n            return this.createError('function.arity', { n }, state, options);\n        },
                                  "name": "arity",
                                  "arg": 1
                                }
                              ],
                              "_refs": [],
                              "_flags": {
                                "func": true
                              },
                              "_description": null,
                              "_unit": null,
                              "_notes": [],
                              "_tags": [],
                              "_examples": [],
                              "_meta": [],
                              "_inner": {
                                "children": null,
                                "renames": [],
                                "dependencies": [],
                                "patterns": []
                              }
                            }
                          },
                          {
                            "key": "validate",
                            "schema": {
                              "isJoi": true,
                              "_currentJoi": "[Circular ~.base._currentJoi]",
                              "_type": "object",
                              "_settings": null,
                              "_valids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_invalids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_tests": [
                                {
                                  "func": function (value, state, options) {\n\n            if (value.length === n) {\n                return value;\n            }\n\n            return this.createError('function.arity', { n }, state, options);\n        },
                                  "name": "arity",
                                  "arg": 4
                                }
                              ],
                              "_refs": [],
                              "_flags": {
                                "func": true
                              },
                              "_description": null,
                              "_unit": null,
                              "_notes": [],
                              "_tags": [],
                              "_examples": [],
                              "_meta": [],
                              "_inner": {
                                "children": null,
                                "renames": [],
                                "dependencies": [],
                                "patterns": []
                              }
                            }
                          },
                          {
                            "key": "params",
                            "schema": {
                              "isJoi": true,
                              "_currentJoi": "[Circular ~.base._currentJoi]",
                              "_type": "alternatives",
                              "_settings": null,
                              "_valids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_invalids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_tests": [],
                              "_refs": [],
                              "_flags": {},
                              "_description": null,
                              "_unit": null,
                              "_notes": [],
                              "_tags": [],
                              "_examples": [],
                              "_meta": [],
                              "_inner": {
                                "matches": [
                                  {
                                    "schema": {
                                      "isJoi": true,
                                      "_currentJoi": "[Circular ~.base._currentJoi]",
                                      "_type": "object",
                                      "_settings": null,
                                      "_valids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_invalids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_tests": [],
                                      "_refs": [],
                                      "_flags": {},
                                      "_description": null,
                                      "_unit": null,
                                      "_notes": [],
                                      "_tags": [],
                                      "_examples": [],
                                      "_meta": [],
                                      "_inner": {
                                        "children": null,
                                        "renames": [],
                                        "dependencies": [],
                                        "patterns": [
                                          {
                                            "regex": {},
                                            "rule": {
                                              "isJoi": true,
                                              "_currentJoi": "[Circular ~.base._currentJoi]",
                                              "_type": "object",
                                              "_settings": null,
                                              "_valids": {
                                                "_set": {},
                                                "_hasRef": false
                                              },
                                              "_invalids": {
                                                "_set": {},
                                                "_hasRef": false
                                              },
                                              "_tests": [
                                                {
                                                  "func": function (value, state, options) {\n\n            if (value instanceof constructor) {\n                return value;\n            }\n\n            return this.createError('object.type', { type: typeData.name, value }, state, options);\n        },
                                                  "name": "type",
                                                  "arg": {
                                                    "name": "Joi object",
                                                    "ctor": "[class {\n\n    constructor() {\n\n        this.isJoi = true;\n        this._type = 'any';\n        this._settings = null;\n        this._valids = new internals.Set();\n        this._invalids = new internals.Set();\n        this._tests = [];\n        this._refs = [];\n        this._flags = {\n            /*\n             presence: 'optional',                   // optional, required, forbidden, ignore\n             allowOnly: false,\n             allowUnknown: undefined,\n             default: undefined,\n             forbidden: false,\n             encoding: undefined,\n             insensitive: false,\n             trim: false,\n             normalize: undefined,                   // NFC, NFD, NFKC, NFKD\n             case: undefined,                        // upper, lower\n             empty: undefined,\n             func: false,\n             raw: false\n             */\n        };\n\n        this._description = null;\n        this._unit = null;\n        this._notes = [];\n        this._tags = [];\n        this._examples = [];\n        this._meta = [];\n\n        this._inner = {};                           // Hash of arrays of immutable objects\n    }\n\n    _init() {\n\n        return this;\n    }\n\n    get schemaType() {\n\n        return this._type;\n    }\n\n    createError(type, context, state, options, flags = this._flags) {\n\n        return Errors.create(type, context, state, options, flags);\n    }\n\n    createOverrideError(type, context, state, options, message, template) {\n\n        return Errors.create(type, context, state, options, this._flags, message, template);\n    }\n\n    checkOptions(options) {\n\n        Schemas = Schemas || require('../../schemas');\n\n        const result = Schemas.options.validate(options);\n\n        if (result.error) {\n            throw new Error(result.error.details[0].message);\n        }\n    }\n\n    clone() {\n\n        const obj = Object.create(Object.getPrototypeOf(this));\n\n        obj.isJoi = true;\n        obj._currentJoi = this._currentJoi;\n        obj._type = this._type;\n        obj._settings = this._settings;\n        obj._baseType = this._baseType;\n        obj._valids = this._valids.slice();\n        obj._invalids = this._invalids.slice();\n        obj._tests = this._tests.slice();\n        obj._refs = this._refs.slice();\n        obj._flags = Hoek.clone(this._flags);\n\n        obj._description = this._description;\n        obj._unit = this._unit;\n        obj._notes = this._notes.slice();\n        obj._tags = this._tags.slice();\n        obj._examples = this._examples.slice();\n        obj._meta = this._meta.slice();\n\n        obj._inner = {};\n        const inners = Object.keys(this._inner);\n        for (let i = 0; i < inners.length; ++i) {\n            const key = inners[i];\n            obj._inner[key] = this._inner[key] ? this._inner[key].slice() : null;\n        }\n\n        return obj;\n    }\n\n    concat(schema) {\n\n        Hoek.assert(schema instanceof internals.Any, 'Invalid schema object');\n        Hoek.assert(this._type === 'any' || schema._type === 'any' || schema._type === this._type, 'Cannot merge type', this._type, 'with another type:', schema._type);\n\n        let obj = this.clone();\n\n        if (this._type === 'any' && schema._type !== 'any') {\n\n            // Reset values as if we were \"this\"\n            const tmpObj = schema.clone();\n            const keysToRestore = ['_settings', '_valids', '_invalids', '_tests', '_refs', '_flags', '_description', '_unit',\n                '_notes', '_tags', '_examples', '_meta', '_inner'];\n\n            for (let i = 0; i < keysToRestore.length; ++i) {\n                tmpObj[keysToRestore[i]] = obj[keysToRestore[i]];\n            }\n\n            obj = tmpObj;\n        }\n\n        obj._settings = obj._settings ? Settings.concat(obj._settings, schema._settings) : schema._settings;\n        obj._valids.merge(schema._valids, schema._invalids);\n        obj._invalids.merge(schema._invalids, schema._valids);\n        obj._tests.push(...schema._tests);\n        obj._refs.push(...schema._refs);\n        if (obj._flags.empty && schema._flags.empty) {\n            obj._flags.empty = obj._flags.empty.concat(schema._flags.empty);\n            const flags = Object.assign({}, schema._flags);\n            delete flags.empty;\n            Hoek.merge(obj._flags, flags);\n        }\n        else if (schema._flags.empty) {\n            obj._flags.empty = schema._flags.empty;\n            const flags = Object.assign({}, schema._flags);\n            delete flags.empty;\n            Hoek.merge(obj._flags, flags);\n        }\n        else {\n            Hoek.merge(obj._flags, schema._flags);\n        }\n\n        obj._description = schema._description || obj._description;\n        obj._unit = schema._unit || obj._unit;\n        obj._notes.push(...schema._notes);\n        obj._tags.push(...schema._tags);\n        obj._examples.push(...schema._examples);\n        obj._meta.push(...schema._meta);\n\n        const inners = Object.keys(schema._inner);\n        const isObject = obj._type === 'object';\n        for (let i = 0; i < inners.length; ++i) {\n            const key = inners[i];\n            const source = schema._inner[key];\n            if (source) {\n                const target = obj._inner[key];\n                if (target) {\n                    if (isObject && key === 'children') {\n                        const keys = {};\n\n                        for (let j = 0; j < target.length; ++j) {\n                            keys[target[j].key] = j;\n                        }\n\n                        for (let j = 0; j < source.length; ++j) {\n                            const sourceKey = source[j].key;\n                            if (keys[sourceKey] >= 0) {\n                                target[keys[sourceKey]] = {\n                                    key: sourceKey,\n                                    schema: target[keys[sourceKey]].schema.concat(source[j].schema)\n                                };\n                            }\n                            else {\n                                target.push(source[j]);\n                            }\n                        }\n                    }\n                    else {\n                        obj._inner[key] = obj._inner[key].concat(source);\n                    }\n                }\n                else {\n                    obj._inner[key] = source.slice();\n                }\n            }\n        }\n\n        return obj;\n    }\n\n    _test(name, arg, func, options) {\n\n        const obj = this.clone();\n        obj._tests.push({ func, name, arg, options });\n        return obj;\n    }\n\n    _testUnique(name, arg, func, options) {\n\n        const obj = this.clone();\n        obj._tests = obj._tests.filter((test) => test.name !== name);\n        obj._tests.push({ func, name, arg, options });\n        return obj;\n    }\n\n    options(options) {\n\n        Hoek.assert(!options.context, 'Cannot override context');\n        this.checkOptions(options);\n\n        const obj = this.clone();\n        obj._settings = Settings.concat(obj._settings, options);\n        return obj;\n    }\n\n    strict(isStrict) {\n\n        const obj = this.clone();\n\n        const convert = isStrict === undefined ? false : !isStrict;\n        obj._settings = Settings.concat(obj._settings, { convert });\n        return obj;\n    }\n\n    raw(isRaw) {\n\n        const value = isRaw === undefined ? true : isRaw;\n\n        if (this._flags.raw === value) {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.raw = value;\n        return obj;\n    }\n\n    error(err, options = { self: false }) {\n\n        Hoek.assert(err && (err instanceof Error || typeof err === 'function'), 'Must provide a valid Error object or a function');\n\n        const unknownKeys = Object.keys(options).filter((k) => !['self'].includes(k));\n        Hoek.assert(unknownKeys.length === 0, `Options ${unknownKeys} are unknown`);\n\n        const obj = this.clone();\n        obj._flags.error = err;\n\n        if (options.self) {\n            obj._flags.selfError = true;\n        }\n\n        return obj;\n    }\n\n    allow(...values) {\n\n        const obj = this.clone();\n        values = Hoek.flatten(values);\n        for (let i = 0; i < values.length; ++i) {\n            const value = values[i];\n\n            Hoek.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');\n            obj._invalids.remove(value);\n            obj._valids.add(value, obj._refs);\n        }\n\n        return obj;\n    }\n\n    valid(...values) {\n\n        const obj = this.allow(...values);\n        obj._flags.allowOnly = true;\n        return obj;\n    }\n\n    invalid(...values) {\n\n        const obj = this.clone();\n        values = Hoek.flatten(values);\n        for (let i = 0; i < values.length; ++i) {\n            const value = values[i];\n\n            Hoek.assert(value !== undefined, 'Cannot call allow/valid/invalid with undefined');\n            obj._valids.remove(value);\n            obj._invalids.add(value, obj._refs);\n        }\n\n        return obj;\n    }\n\n    required() {\n\n        if (this._flags.presence === 'required') {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.presence = 'required';\n        return obj;\n    }\n\n    optional() {\n\n        if (this._flags.presence === 'optional') {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.presence = 'optional';\n        return obj;\n    }\n\n\n    forbidden() {\n\n        if (this._flags.presence === 'forbidden') {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.presence = 'forbidden';\n        return obj;\n    }\n\n\n    strip() {\n\n        if (this._flags.strip) {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.strip = true;\n        return obj;\n    }\n\n    applyFunctionToChildren(children, fn, args = [], root) {\n\n        children = [].concat(children);\n\n        if (children.length !== 1 || children[0] !== '') {\n            root = root ? (root + '.') : '';\n\n            const extraChildren = (children[0] === '' ? children.slice(1) : children).map((child) => {\n\n                return root + child;\n            });\n\n            throw new Error('unknown key(s) ' + extraChildren.join(', '));\n        }\n\n        return this[fn](...args);\n    }\n\n    default(value, description) {\n\n        if (typeof value === 'function' &&\n            !Ref.isRef(value)) {\n\n            if (!value.description &&\n                description) {\n\n                value.description = description;\n            }\n\n            if (!this._flags.func) {\n                Hoek.assert(typeof value.description === 'string' && value.description.length > 0, 'description must be provided when default value is a function');\n            }\n        }\n\n        const obj = this.clone();\n        obj._flags.default = value;\n        Ref.push(obj._refs, value);\n        return obj;\n    }\n\n    empty(schema) {\n\n        const obj = this.clone();\n        if (schema === undefined) {\n            delete obj._flags.empty;\n        }\n        else {\n            obj._flags.empty = Cast.schema(this._currentJoi, schema);\n        }\n\n        return obj;\n    }\n\n    when(condition, options) {\n\n        Hoek.assert(options && typeof options === 'object', 'Invalid options');\n        Hoek.assert(options.then !== undefined || options.otherwise !== undefined, 'options must have at least one of \"then\" or \"otherwise\"');\n\n        const then = options.hasOwnProperty('then') ? this.concat(Cast.schema(this._currentJoi, options.then)) : undefined;\n        const otherwise = options.hasOwnProperty('otherwise') ? this.concat(Cast.schema(this._currentJoi, options.otherwise)) : undefined;\n\n        Alternatives = Alternatives || require('../alternatives');\n\n        const alternativeOptions = { then, otherwise };\n        if (Object.prototype.hasOwnProperty.call(options, 'is')) {\n            alternativeOptions.is = options.is;\n        }\n\n        const obj = Alternatives.when(condition, alternativeOptions);\n        obj._flags.presence = 'ignore';\n        obj._baseType = this;\n\n        return obj;\n    }\n\n    description(desc) {\n\n        Hoek.assert(desc && typeof desc === 'string', 'Description must be a non-empty string');\n\n        const obj = this.clone();\n        obj._description = desc;\n        return obj;\n    }\n\n    notes(notes) {\n\n        Hoek.assert(notes && (typeof notes === 'string' || Array.isArray(notes)), 'Notes must be a non-empty string or array');\n\n        const obj = this.clone();\n        obj._notes = obj._notes.concat(notes);\n        return obj;\n    }\n\n    tags(tags) {\n\n        Hoek.assert(tags && (typeof tags === 'string' || Array.isArray(tags)), 'Tags must be a non-empty string or array');\n\n        const obj = this.clone();\n        obj._tags = obj._tags.concat(tags);\n        return obj;\n    }\n\n    meta(meta) {\n\n        Hoek.assert(meta !== undefined, 'Meta cannot be undefined');\n\n        const obj = this.clone();\n        obj._meta = obj._meta.concat(meta);\n        return obj;\n    }\n\n    example(...examples) {\n\n        Hoek.assert(examples.length > 0, 'Missing examples');\n\n        const processed = [];\n        for (let i = 0; i < examples.length; ++i) {\n            const example = [].concat(examples[i]);\n            Hoek.assert(example.length <= 2, `Bad example format at index ${i}`);\n\n            const value = example[0];\n            let options = example[1];\n            if (options !== undefined) {\n                Hoek.assert(options && typeof options === 'object', `Options for example at index ${i} must be an object`);\n                const unknownOptions = Object.keys(options).filter((option) => !['parent', 'context'].includes(option));\n                Hoek.assert(unknownOptions.length === 0, `Unknown example options ${unknownOptions} at index ${i}`);\n            }\n            else {\n                options = {};\n            }\n\n            const localState = new State('', [], options.parent || null);\n            const result = this._validate(value, localState, Settings.concat(internals.defaults, options.context ? { context: options.context } : null));\n            Hoek.assert(!result.errors, `Bad example at index ${i}:`, result.errors && Errors.process(result.errors, value));\n\n            const ex = { value };\n            if (Object.keys(options).length) {\n                ex.options = options;\n            }\n\n            processed.push(ex);\n        }\n\n        const obj = this.clone();\n        obj._examples = processed;\n        return obj;\n    }\n\n    unit(name) {\n\n        Hoek.assert(name && typeof name === 'string', 'Unit name must be a non-empty string');\n\n        const obj = this.clone();\n        obj._unit = name;\n        return obj;\n    }\n\n    _prepareEmptyValue(value) {\n\n        if (typeof value === 'string' && this._flags.trim) {\n            return value.trim();\n        }\n\n        return value;\n    }\n\n    _validate(value, state, options, reference) {\n\n        const originalValue = value;\n\n        // Setup state and settings\n\n        state = state || new State('', [], null, reference);\n\n        if (this._settings) {\n            const isDefaultOptions = options === internals.defaults;\n            if (isDefaultOptions && this._settings[Symbols.settingsCache]) {\n                options = this._settings[Symbols.settingsCache];\n            }\n            else {\n                options = Settings.concat(this._language ? Settings.concat({ language: this._language }, options) : options, this._settings);\n                if (isDefaultOptions) {\n                    this._settings[Symbols.settingsCache] = options;\n                }\n            }\n        }\n        else if (this._language) {\n            options = Settings.concat({ language: this._language }, options);\n        }\n\n        let errors = [];\n\n        if (this._coerce) {\n            const coerced = this._coerce(value, state, options);\n            if (coerced.errors) {\n                value = coerced.value;\n                errors = errors.concat(coerced.errors);\n                return this._finalizeValue(value, originalValue, errors, state, options);                            // Coerced error always aborts early\n            }\n\n            value = coerced.value;\n        }\n\n        if (this._flags.empty && !this._flags.empty._validate(this._prepareEmptyValue(value), null, internals.defaults).errors) {\n            value = undefined;\n        }\n\n        // Check presence requirements\n\n        const presence = this._flags.presence || options.presence;\n        if (presence === 'optional') {\n            if (value === undefined) {\n                const isDeepDefault = this._flags.hasOwnProperty('default') && this._flags.default === undefined;\n                if (isDeepDefault && this._type === 'object') {\n                    value = {};\n                }\n                else {\n                    return this._finalizeValue(value, originalValue, errors, state, options);\n                }\n            }\n        }\n        else if (presence === 'required' &&\n            value === undefined) {\n\n            errors.push(this.createError('any.required', null, state, options));\n            return this._finalizeValue(value, originalValue, errors, state, options);\n        }\n        else if (presence === 'forbidden') {\n            if (value === undefined) {\n                return this._finalizeValue(value, originalValue, errors, state, options);\n            }\n\n            errors.push(this.createError('any.unknown', null, state, options));\n            return this._finalizeValue(value, originalValue, errors, state, options);\n        }\n\n        // Check allowed and denied values using the original value\n\n        let match = this._valids.get(value, state, options, this._flags.insensitive);\n        if (match) {\n            if (options.convert) {\n                value = match.value;\n            }\n\n            return this._finalizeValue(value, originalValue, errors, state, options);\n        }\n\n        if (this._invalids.has(value, state, options, this._flags.insensitive)) {\n            errors.push(this.createError(value === '' ? 'any.empty' : 'any.invalid', { value, invalids: this._invalids.values({ stripUndefined: true }) }, state, options));\n            if (options.abortEarly) {\n\n                return this._finalizeValue(value, originalValue, errors, state, options);\n            }\n        }\n\n        // Convert value and validate type\n\n        if (this._base) {\n            const base = this._base(value, state, options);\n            if (base.errors) {\n                value = base.value;\n                errors = errors.concat(base.errors);\n                return this._finalizeValue(value, originalValue, errors, state, options);                            // Base error always aborts early\n            }\n\n            if (base.value !== value) {\n                value = base.value;\n\n                // Check allowed and denied values using the converted value\n\n                match = this._valids.get(value, state, options, this._flags.insensitive);\n                if (match) {\n                    value = match.value;\n                    return this._finalizeValue(value, originalValue, errors, state, options);\n                }\n\n                if (this._invalids.has(value, state, options, this._flags.insensitive)) {\n                    errors.push(this.createError(value === '' ? 'any.empty' : 'any.invalid', { value, invalids: this._invalids.values({ stripUndefined: true }) }, state, options));\n                    if (options.abortEarly) {\n                        return this._finalizeValue(value, originalValue, errors, state, options);\n                    }\n                }\n            }\n        }\n\n        // Required values did not match\n\n        if (this._flags.allowOnly) {\n            errors.push(this.createError('any.allowOnly', { value, valids: this._valids.values({ stripUndefined: true }) }, state, options));\n            if (options.abortEarly) {\n                return this._finalizeValue(value, originalValue, errors, state, options);\n            }\n        }\n\n        // Validate tests\n\n        for (let i = 0; i < this._tests.length; ++i) {\n            const test = this._tests[i];\n            const ret = test.func.call(this, value, state, options);\n            if (ret instanceof Errors.Err) {\n                errors.push(ret);\n                if (options.abortEarly) {\n                    return this._finalizeValue(value, originalValue, errors, state, options);\n                }\n            }\n            else {\n                value = ret;\n            }\n        }\n\n        return this._finalizeValue(value, originalValue, errors, state, options);\n    }\n\n    _finalizeValue(value, originalValue, errors, state, options) {\n\n        let finalValue;\n\n        if (value !== undefined) {\n            finalValue = this._flags.raw ? originalValue : value;\n        }\n        else if (options.noDefaults) {\n            finalValue = value;\n        }\n        else if (Ref.isRef(this._flags.default)) {\n            finalValue = this._flags.default(state.parent, options);\n        }\n        else if (typeof this._flags.default === 'function' &&\n            !(this._flags.func && !this._flags.default.description)) {\n\n            let args;\n\n            if (state.parent !== null &&\n                this._flags.default.length > 0) {\n\n                args = [Hoek.clone(state.parent), options];\n            }\n\n            const defaultValue = internals._try(this._flags.default, args);\n            finalValue = defaultValue.value;\n            if (defaultValue.error) {\n                errors.push(this.createError('any.default', { error: defaultValue.error }, state, options));\n            }\n        }\n        else {\n            finalValue = Hoek.clone(this._flags.default);\n        }\n\n        if (errors.length &&\n            typeof this._flags.error === 'function' &&\n            (\n                !this._flags.selfError ||\n                errors.some((e) => state.path.length === e.path.length)\n            )\n        ) {\n            const change = this._flags.error.call(this, errors);\n\n            if (typeof change === 'string') {\n                errors = [this.createOverrideError('override', { reason: errors }, state, options, change)];\n            }\n            else {\n                errors = [].concat(change)\n                    .map((err) => {\n\n                        return err instanceof Error ?\n                            err :\n                            this.createOverrideError(err.type || 'override', err.context, state, options, err.message, err.template);\n                    });\n            }\n        }\n\n        return {\n            value: this._flags.strip ? undefined : finalValue,\n            finalValue,\n            errors: errors.length ? errors : null\n        };\n    }\n\n    _validateWithOptions(value, options, callback) {\n\n        if (options) {\n            this.checkOptions(options);\n        }\n\n        const settings = Settings.concat(internals.defaults, options);\n        const result = this._validate(value, null, settings);\n        const errors = Errors.process(result.errors, value);\n\n        if (callback) {\n            return callback(errors, result.value);\n        }\n\n        return {\n            error: errors,\n            value: result.value,\n            then(resolve, reject) {\n\n                if (errors) {\n                    return Promise.reject(errors).catch(reject);\n                }\n\n                return Promise.resolve(result.value).then(resolve);\n            },\n            catch(reject) {\n\n                if (errors) {\n                    return Promise.reject(errors).catch(reject);\n                }\n\n                return Promise.resolve(result.value);\n            }\n        };\n    }\n\n    validate(value, options, callback) {\n\n        if (typeof options === 'function') {\n            return this._validateWithOptions(value, null, options);\n        }\n\n        return this._validateWithOptions(value, options, callback);\n    }\n\n    describe() {\n\n        const description = {\n            type: this._type\n        };\n\n        const flags = Object.keys(this._flags);\n        if (flags.length) {\n            if (['empty', 'default', 'lazy', 'label'].some((flag) => this._flags.hasOwnProperty(flag))) {\n                description.flags = {};\n                for (let i = 0; i < flags.length; ++i) {\n                    const flag = flags[i];\n                    if (flag === 'empty') {\n                        description.flags[flag] = this._flags[flag].describe();\n                    }\n                    else if (flag === 'default') {\n                        if (Ref.isRef(this._flags[flag])) {\n                            description.flags[flag] = this._flags[flag].toString();\n                        }\n                        else if (typeof this._flags[flag] === 'function') {\n                            description.flags[flag] = {\n                                description: this._flags[flag].description,\n                                function   : this._flags[flag]\n                            };\n                        }\n                        else {\n                            description.flags[flag] = this._flags[flag];\n                        }\n                    }\n                    else if (flag === 'lazy' || flag === 'label') {\n                        // We don't want it in the description\n                    }\n                    else {\n                        description.flags[flag] = this._flags[flag];\n                    }\n                }\n            }\n            else {\n                description.flags = this._flags;\n            }\n        }\n\n        if (this._settings) {\n            description.options = Hoek.clone(this._settings);\n        }\n\n        if (this._baseType) {\n            description.base = this._baseType.describe();\n        }\n\n        if (this._description) {\n            description.description = this._description;\n        }\n\n        if (this._notes.length) {\n            description.notes = this._notes;\n        }\n\n        if (this._tags.length) {\n            description.tags = this._tags;\n        }\n\n        if (this._meta.length) {\n            description.meta = this._meta;\n        }\n\n        if (this._examples.length) {\n            description.examples = this._examples;\n        }\n\n        if (this._unit) {\n            description.unit = this._unit;\n        }\n\n        const valids = this._valids.values();\n        if (valids.length) {\n            description.valids = valids.map((v) => {\n\n                return Ref.isRef(v) ? v.toString() : v;\n            });\n        }\n\n        const invalids = this._invalids.values();\n        if (invalids.length) {\n            description.invalids = invalids.map((v) => {\n\n                return Ref.isRef(v) ? v.toString() : v;\n            });\n        }\n\n        description.rules = [];\n\n        for (let i = 0; i < this._tests.length; ++i) {\n            const validator = this._tests[i];\n            const item = { name: validator.name };\n\n            if (validator.arg !== void 0) {\n                item.arg = Ref.isRef(validator.arg) ? validator.arg.toString() : validator.arg;\n            }\n\n            const options = validator.options;\n            if (options) {\n                if (options.hasRef) {\n                    item.arg = {};\n                    const keys = Object.keys(validator.arg);\n                    for (let j = 0; j < keys.length; ++j) {\n                        const key = keys[j];\n                        const value = validator.arg[key];\n                        item.arg[key] = Ref.isRef(value) ? value.toString() : value;\n                    }\n                }\n\n                if (typeof options.description === 'string') {\n                    item.description = options.description;\n                }\n                else if (typeof options.description === 'function') {\n                    item.description = options.description(item.arg);\n                }\n            }\n\n            description.rules.push(item);\n        }\n\n        if (!description.rules.length) {\n            delete description.rules;\n        }\n\n        const label = this._getLabel();\n        if (label) {\n            description.label = label;\n        }\n\n        return description;\n    }\n\n    label(name) {\n\n        Hoek.assert(name && typeof name === 'string', 'Label name must be a non-empty string');\n\n        const obj = this.clone();\n        obj._flags.label = name;\n        return obj;\n    }\n\n    _getLabel(def) {\n\n        return this._flags.label || def;\n    }\n\n}]"
                                                  }
                                                }
                                              ],
                                              "_refs": [],
                                              "_flags": {},
                                              "_description": null,
                                              "_unit": null,
                                              "_notes": [],
                                              "_tags": [],
                                              "_examples": [],
                                              "_meta": [],
                                              "_inner": {
                                                "children": null,
                                                "renames": [],
                                                "dependencies": [],
                                                "patterns": []
                                              }
                                            }
                                          }
                                        ]
                                      }
                                    }
                                  },
                                  {
                                    "schema": {
                                      "isJoi": true,
                                      "_currentJoi": "[Circular ~.base._currentJoi]",
                                      "_type": "object",
                                      "_settings": null,
                                      "_valids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_invalids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_tests": [
                                        {
                                          "func": function (value, state, options) {\n\n            if (value instanceof constructor) {\n                return value;\n            }\n\n            return this.createError('object.type', { type: typeData.name, value }, state, options);\n        },
                                          "name": "type",
                                          "arg": {
                                            "name": "Joi object",
                                            "ctor": "[class extends Any {\n\n    constructor() {\n\n        super();\n        this._type = 'object';\n        this._inner.children = null;\n        this._inner.renames = [];\n        this._inner.dependencies = [];\n        this._inner.patterns = [];\n    }\n\n    _init(...args) {\n\n        return args.length ? this.keys(...args) : this;\n    }\n\n    _base(value, state, options) {\n\n        let target = value;\n        const errors = [];\n        const finish = () => {\n\n            return {\n                value: target,\n                errors: errors.length ? errors : null\n            };\n        };\n\n        if (typeof value === 'string' &&\n            options.convert) {\n\n            if (value.length > 1 &&\n                (value[0] === '{' || /^\\s*\\{/.test(value))) {\n\n                try {\n                    value = Bourne.parse(value);\n                }\n                catch (e) { }\n            }\n        }\n\n        const type = this._flags.func ? 'function' : 'object';\n        if (!value ||\n            typeof value !== type ||\n            Array.isArray(value)) {\n\n            errors.push(this.createError(type + '.base', { value }, state, options));\n            return finish();\n        }\n\n        // Skip if there are no other rules to test\n\n        if (!this._inner.renames.length &&\n            !this._inner.dependencies.length &&\n            !this._inner.children &&                    // null allows any keys\n            !this._inner.patterns.length) {\n\n            target = value;\n            return finish();\n        }\n\n        // Ensure target is a local copy (parsed) or shallow copy\n\n        if (target === value) {\n            if (type === 'object') {\n                target = Object.create(Object.getPrototypeOf(value));\n            }\n            else {\n                target = function (...args) {\n\n                    return value.apply(this, args);\n                };\n\n                target.prototype = Hoek.clone(value.prototype);\n            }\n\n            const valueKeys = Object.keys(value);\n            for (let i = 0; i < valueKeys.length; ++i) {\n                target[valueKeys[i]] = value[valueKeys[i]];\n            }\n        }\n        else {\n            target = value;\n        }\n\n        // Rename keys\n\n        const renamed = {};\n        for (let i = 0; i < this._inner.renames.length; ++i) {\n            const rename = this._inner.renames[i];\n\n            if (rename.isRegExp) {\n                const targetKeys = Object.keys(target);\n                const matchedTargetKeys = [];\n\n                for (let j = 0; j < targetKeys.length; ++j) {\n                    if (rename.from.test(targetKeys[j])) {\n                        matchedTargetKeys.push(targetKeys[j]);\n                    }\n                }\n\n                const allUndefined = matchedTargetKeys.every((key) => target[key] === undefined);\n                if (rename.options.ignoreUndefined && allUndefined) {\n                    continue;\n                }\n\n                if (!rename.options.multiple &&\n                    renamed[rename.to]) {\n\n                    errors.push(this.createError('object.rename.regex.multiple', { from: matchedTargetKeys, to: rename.to }, state, options));\n                    if (options.abortEarly) {\n                        return finish();\n                    }\n                }\n\n                if (Object.prototype.hasOwnProperty.call(target, rename.to) &&\n                    !rename.options.override &&\n                    !renamed[rename.to]) {\n\n                    errors.push(this.createError('object.rename.regex.override', { from: matchedTargetKeys, to: rename.to }, state, options));\n                    if (options.abortEarly) {\n                        return finish();\n                    }\n                }\n\n                if (allUndefined) {\n                    delete target[rename.to];\n                }\n                else {\n                    target[rename.to] = target[matchedTargetKeys[matchedTargetKeys.length - 1]];\n                }\n\n                renamed[rename.to] = true;\n\n                if (!rename.options.alias) {\n                    for (let j = 0; j < matchedTargetKeys.length; ++j) {\n                        delete target[matchedTargetKeys[j]];\n                    }\n                }\n            }\n            else {\n                if (rename.options.ignoreUndefined && target[rename.from] === undefined) {\n                    continue;\n                }\n\n                if (!rename.options.multiple &&\n                    renamed[rename.to]) {\n\n                    errors.push(this.createError('object.rename.multiple', { from: rename.from, to: rename.to }, state, options));\n                    if (options.abortEarly) {\n                        return finish();\n                    }\n                }\n\n                if (Object.prototype.hasOwnProperty.call(target, rename.to) &&\n                    !rename.options.override &&\n                    !renamed[rename.to]) {\n\n                    errors.push(this.createError('object.rename.override', { from: rename.from, to: rename.to }, state, options));\n                    if (options.abortEarly) {\n                        return finish();\n                    }\n                }\n\n                if (target[rename.from] === undefined) {\n                    delete target[rename.to];\n                }\n                else {\n                    target[rename.to] = target[rename.from];\n                }\n\n                renamed[rename.to] = true;\n\n                if (!rename.options.alias) {\n                    delete target[rename.from];\n                }\n            }\n        }\n\n        // Validate schema\n\n        if (!this._inner.children &&            // null allows any keys\n            !this._inner.patterns.length &&\n            !this._inner.dependencies.length) {\n\n            return finish();\n        }\n\n        const unprocessed = new Set(Object.keys(target));\n\n        if (this._inner.children) {\n            const stripProps = [];\n\n            for (let i = 0; i < this._inner.children.length; ++i) {\n                const child = this._inner.children[i];\n                const key = child.key;\n                const item = target[key];\n\n                unprocessed.delete(key);\n\n                const localState = new State(key, [...state.path, key], target, state.reference);\n                const result = child.schema._validate(item, localState, options);\n                if (result.errors) {\n                    errors.push(this.createError('object.child', { key, child: child.schema._getLabel(key), reason: result.errors }, localState, options));\n\n                    if (options.abortEarly) {\n                        return finish();\n                    }\n                }\n                else {\n                    if (child.schema._flags.strip || (result.value === undefined && result.value !== item)) {\n                        stripProps.push(key);\n                        target[key] = result.finalValue;\n                    }\n                    else if (result.value !== undefined) {\n                        target[key] = result.value;\n                    }\n                }\n            }\n\n            for (let i = 0; i < stripProps.length; ++i) {\n                delete target[stripProps[i]];\n            }\n        }\n\n        // Unknown keys\n\n        if (unprocessed.size && this._inner.patterns.length) {\n\n            for (const key of unprocessed) {\n                const localState = new State(key, [...state.path, key], target, state.reference);\n                const item = target[key];\n\n                for (let i = 0; i < this._inner.patterns.length; ++i) {\n                    const pattern = this._inner.patterns[i];\n\n                    if (pattern.regex ?\n                        pattern.regex.test(key) :\n                        !pattern.schema._validate(key, state, { ...options, abortEarly:true }).errors) {\n\n                        unprocessed.delete(key);\n\n                        const result = pattern.rule._validate(item, localState, options);\n                        if (result.errors) {\n                            errors.push(this.createError('object.child', {\n                                key,\n                                child: pattern.rule._getLabel(key),\n                                reason: result.errors\n                            }, localState, options));\n\n                            if (options.abortEarly) {\n                                return finish();\n                            }\n                        }\n\n                        target[key] = result.value;\n                    }\n                }\n            }\n        }\n\n        if (unprocessed.size && (this._inner.children || this._inner.patterns.length)) {\n            if ((options.stripUnknown && this._flags.allowUnknown !== true) ||\n                options.skipFunctions) {\n\n                const stripUnknown = options.stripUnknown\n                    ? (options.stripUnknown === true ? true : !!options.stripUnknown.objects)\n                    : false;\n\n\n                for (const key of unprocessed) {\n                    if (stripUnknown) {\n                        delete target[key];\n                        unprocessed.delete(key);\n                    }\n                    else if (typeof target[key] === 'function') {\n                        unprocessed.delete(key);\n                    }\n                }\n            }\n\n            if ((this._flags.allowUnknown !== undefined ? !this._flags.allowUnknown : !options.allowUnknown)) {\n\n                for (const unprocessedKey of unprocessed) {\n                    errors.push(this.createError('object.allowUnknown', { child: unprocessedKey, value: target[unprocessedKey] }, {\n                        key: unprocessedKey,\n                        path: [...state.path, unprocessedKey]\n                    }, options, {}));\n                }\n            }\n        }\n\n        // Validate dependencies\n\n        for (let i = 0; i < this._inner.dependencies.length; ++i) {\n            const dep = this._inner.dependencies[i];\n            const hasKey = dep.key !== null;\n            const splitKey = hasKey && dep.key.split('.');\n            const localState = hasKey ? new State(splitKey[splitKey.length - 1], [...state.path, ...splitKey]) : new State(null, state.path);\n            const err = internals[dep.type].call(this, dep.key, hasKey && Hoek.reach(target, dep.key, { functions: true }), dep.peers, target, localState, options);\n            if (err instanceof Errors.Err) {\n                errors.push(err);\n                if (options.abortEarly) {\n                    return finish();\n                }\n            }\n        }\n\n        return finish();\n    }\n\n    keys(schema) {\n\n        Hoek.assert(schema === null || schema === undefined || typeof schema === 'object', 'Object schema must be a valid object');\n        Hoek.assert(!schema || !(schema instanceof Any), 'Object schema cannot be a joi schema');\n\n        const obj = this.clone();\n\n        if (!schema) {\n            obj._inner.children = null;\n            return obj;\n        }\n\n        const children = Object.keys(schema);\n\n        if (!children.length) {\n            obj._inner.children = [];\n            return obj;\n        }\n\n        const topo = new Topo();\n        if (obj._inner.children) {\n            for (let i = 0; i < obj._inner.children.length; ++i) {\n                const child = obj._inner.children[i];\n\n                // Only add the key if we are not going to replace it later\n                if (!children.includes(child.key)) {\n                    topo.add(child, { after: child._refs, group: child.key });\n                }\n            }\n        }\n\n        for (let i = 0; i < children.length; ++i) {\n            const key = children[i];\n            const child = schema[key];\n            try {\n                const cast = Cast.schema(this._currentJoi, child);\n                topo.add({ key, schema: cast }, { after: cast._refs, group: key });\n            }\n            catch (castErr) {\n                if (castErr.hasOwnProperty('path')) {\n                    castErr.path = key + '.' + castErr.path;\n                }\n                else {\n                    castErr.path = key;\n                }\n\n                throw castErr;\n            }\n        }\n\n        obj._inner.children = topo.nodes;\n\n        return obj;\n    }\n\n    append(schema) {\n        // Skip any changes\n        if (schema === null || schema === undefined || Object.keys(schema).length === 0) {\n            return this;\n        }\n\n        return this.keys(schema);\n    }\n\n    unknown(allow) {\n\n        const value = allow !== false;\n\n        if (this._flags.allowUnknown === value) {\n            return this;\n        }\n\n        const obj = this.clone();\n        obj._flags.allowUnknown = value;\n        return obj;\n    }\n\n    length(limit) {\n\n        Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');\n\n        return this._test('length', limit, function (value, state, options) {\n\n            if (Object.keys(value).length === limit) {\n                return value;\n            }\n\n            return this.createError('object.length', { limit, value }, state, options);\n        });\n    }\n\n    min(limit) {\n\n        Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');\n\n        return this._test('min', limit, function (value, state, options) {\n\n            if (Object.keys(value).length >= limit) {\n                return value;\n            }\n\n            return this.createError('object.min', { limit, value }, state, options);\n        });\n    }\n\n    max(limit) {\n\n        Hoek.assert(Number.isSafeInteger(limit) && limit >= 0, 'limit must be a positive integer');\n\n        return this._test('max', limit, function (value, state, options) {\n\n            if (Object.keys(value).length <= limit) {\n                return value;\n            }\n\n            return this.createError('object.max', { limit, value }, state, options);\n        });\n    }\n\n    pattern(pattern, schema) {\n\n        const isRegExp = pattern instanceof RegExp;\n        Hoek.assert(isRegExp || pattern instanceof Any, 'pattern must be a regex or schema');\n        Hoek.assert(schema !== undefined, 'Invalid rule');\n\n        if (isRegExp) {\n            Hoek.assert(!pattern.flags.includes('g') && !pattern.flags.includes('y'), 'pattern should not use global or sticky mode');\n        }\n\n        try {\n            schema = Cast.schema(this._currentJoi, schema);\n        }\n        catch (castErr) {\n            if (castErr.hasOwnProperty('path')) {\n                castErr.message = `${castErr.message}(${castErr.path})`;\n            }\n\n            throw castErr;\n        }\n\n        const obj = this.clone();\n        if (isRegExp) {\n            obj._inner.patterns.push({ regex: pattern, rule: schema });\n        }\n        else {\n            obj._inner.patterns.push({ schema: pattern, rule: schema });\n        }\n\n        return obj;\n    }\n\n    schema() {\n\n        return this._test('schema', null, function (value, state, options) {\n\n            if (value instanceof Any) {\n                return value;\n            }\n\n            return this.createError('object.schema', null, state, options);\n        });\n    }\n\n    with(key, peers) {\n\n        Hoek.assert(arguments.length === 2, 'Invalid number of arguments, expected 2.');\n\n        return this._dependency('with', key, peers);\n    }\n\n    without(key, peers) {\n\n        Hoek.assert(arguments.length === 2, 'Invalid number of arguments, expected 2.');\n\n        return this._dependency('without', key, peers);\n    }\n\n    xor(...peers) {\n\n        peers = Hoek.flatten(peers);\n        return this._dependency('xor', null, peers);\n    }\n\n    oxor(...peers) {\n\n        return this._dependency('oxor', null, peers);\n    }\n\n    or(...peers) {\n\n        peers = Hoek.flatten(peers);\n        return this._dependency('or', null, peers);\n    }\n\n    and(...peers) {\n\n        peers = Hoek.flatten(peers);\n        return this._dependency('and', null, peers);\n    }\n\n    nand(...peers) {\n\n        peers = Hoek.flatten(peers);\n        return this._dependency('nand', null, peers);\n    }\n\n    requiredKeys(...children) {\n\n        children = Hoek.flatten(children);\n        return this.applyFunctionToChildren(children, 'required');\n    }\n\n    optionalKeys(...children) {\n\n        children = Hoek.flatten(children);\n        return this.applyFunctionToChildren(children, 'optional');\n    }\n\n    forbiddenKeys(...children) {\n\n        children = Hoek.flatten(children);\n        return this.applyFunctionToChildren(children, 'forbidden');\n    }\n\n    rename(from, to, options) {\n\n        Hoek.assert(typeof from === 'string' || from instanceof RegExp, 'Rename missing the from argument');\n        Hoek.assert(typeof to === 'string', 'Rename missing the to argument');\n        Hoek.assert(to !== from, 'Cannot rename key to same name:', from);\n\n        for (let i = 0; i < this._inner.renames.length; ++i) {\n            Hoek.assert(this._inner.renames[i].from !== from, 'Cannot rename the same key multiple times');\n        }\n\n        const obj = this.clone();\n\n        obj._inner.renames.push({\n            from,\n            to,\n            options: Hoek.applyToDefaults(internals.renameDefaults, options || {}),\n            isRegExp: from instanceof RegExp\n        });\n\n        return obj;\n    }\n\n    applyFunctionToChildren(children, fn, args = [], root) {\n\n        children = [].concat(children);\n        Hoek.assert(children.length > 0, 'expected at least one children');\n\n        const groupedChildren = internals.groupChildren(children);\n        let obj;\n\n        if ('' in groupedChildren) {\n            obj = this[fn](...args);\n            delete groupedChildren[''];\n        }\n        else {\n            obj = this.clone();\n        }\n\n        if (obj._inner.children) {\n            root = root ? (root + '.') : '';\n\n            for (let i = 0; i < obj._inner.children.length; ++i) {\n                const child = obj._inner.children[i];\n                const group = groupedChildren[child.key];\n\n                if (group) {\n                    obj._inner.children[i] = {\n                        key: child.key,\n                        _refs: child._refs,\n                        schema: child.schema.applyFunctionToChildren(group, fn, args, root + child.key)\n                    };\n\n                    delete groupedChildren[child.key];\n                }\n            }\n        }\n\n        const remaining = Object.keys(groupedChildren);\n        Hoek.assert(remaining.length === 0, 'unknown key(s)', remaining.join(', '));\n\n        return obj;\n    }\n\n    _dependency(type, key, peers) {\n\n        peers = [].concat(peers);\n        for (let i = 0; i < peers.length; ++i) {\n            Hoek.assert(typeof peers[i] === 'string', type, 'peers must be a string or array of strings');\n        }\n\n        const obj = this.clone();\n        obj._inner.dependencies.push({ type, key, peers });\n        return obj;\n    }\n\n    describe(shallow) {\n\n        const description = super.describe();\n\n        if (description.rules) {\n            for (let i = 0; i < description.rules.length; ++i) {\n                const rule = description.rules[i];\n                // Coverage off for future-proof descriptions, only object().assert() is use right now\n                if (/* $lab:coverage:off$ */rule.arg &&\n                    typeof rule.arg === 'object' &&\n                    rule.arg.schema &&\n                    rule.arg.ref /* $lab:coverage:on$ */) {\n                    rule.arg = {\n                        schema: rule.arg.schema.describe(),\n                        ref: rule.arg.ref.toString()\n                    };\n                }\n            }\n        }\n\n        if (this._inner.children &&\n            !shallow) {\n\n            description.children = {};\n            for (let i = 0; i < this._inner.children.length; ++i) {\n                const child = this._inner.children[i];\n                description.children[child.key] = child.schema.describe();\n            }\n        }\n\n        if (this._inner.dependencies.length) {\n            description.dependencies = Hoek.clone(this._inner.dependencies);\n        }\n\n        if (this._inner.patterns.length) {\n            description.patterns = [];\n\n            for (let i = 0; i < this._inner.patterns.length; ++i) {\n                const pattern = this._inner.patterns[i];\n                if (pattern.regex) {\n                    description.patterns.push({ regex: pattern.regex.toString(), rule: pattern.rule.describe() });\n                }\n                else {\n                    description.patterns.push({ schema: pattern.schema.describe(), rule: pattern.rule.describe() });\n                }\n            }\n        }\n\n        if (this._inner.renames.length > 0) {\n            description.renames = Hoek.clone(this._inner.renames);\n        }\n\n        return description;\n    }\n\n    assert(ref, schema, message) {\n\n        ref = Cast.ref(ref);\n        Hoek.assert(ref.isContext || ref.depth > 1, 'Cannot use assertions for root level references - use direct key rules instead');\n        message = message || 'pass the assertion test';\n        Hoek.assert(typeof message === 'string', 'Message must be a string');\n\n        try {\n            schema = Cast.schema(this._currentJoi, schema);\n        }\n        catch (castErr) {\n            if (castErr.hasOwnProperty('path')) {\n                castErr.message = `${castErr.message}(${castErr.path})`;\n            }\n\n            throw castErr;\n        }\n\n        const key = ref.path[ref.path.length - 1];\n        const path = ref.path.join('.');\n\n        return this._test('assert', { schema, ref }, function (value, state, options) {\n\n            const result = schema._validate(ref(value), null, options, value);\n            if (!result.errors) {\n                return value;\n            }\n\n            const localState = new State(key, ref.path, state.parent, state.reference);\n            return this.createError('object.assert', { ref: path, message }, localState, options);\n        });\n    }\n\n    type(constructor, name = constructor.name) {\n\n        Hoek.assert(typeof constructor === 'function', 'type must be a constructor function');\n        const typeData = {\n            name,\n            ctor: constructor\n        };\n\n        return this._test('type', typeData, function (value, state, options) {\n\n            if (value instanceof constructor) {\n                return value;\n            }\n\n            return this.createError('object.type', { type: typeData.name, value }, state, options);\n        });\n    }\n}]"
                                          }
                                        }
                                      ],
                                      "_refs": [],
                                      "_flags": {},
                                      "_description": null,
                                      "_unit": null,
                                      "_notes": [],
                                      "_tags": [],
                                      "_examples": [],
                                      "_meta": [],
                                      "_inner": {
                                        "children": null,
                                        "renames": [],
                                        "dependencies": [],
                                        "patterns": []
                                      }
                                    }
                                  }
                                ]
                              }
                            }
                          },
                          {
                            "key": "description",
                            "schema": {
                              "isJoi": true,
                              "_currentJoi": "[Circular ~.base._currentJoi]",
                              "_type": "alternatives",
                              "_settings": null,
                              "_valids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_invalids": {
                                "_set": {},
                                "_hasRef": false
                              },
                              "_tests": [],
                              "_refs": [],
                              "_flags": {},
                              "_description": null,
                              "_unit": null,
                              "_notes": [],
                              "_tags": [],
                              "_examples": [],
                              "_meta": [],
                              "_inner": {
                                "matches": [
                                  {
                                    "schema": {
                                      "isJoi": true,
                                      "_type": "string",
                                      "_settings": null,
                                      "_valids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_invalids": {
                                        "_set": {},
                                        "_hasRef": 0
                                      },
                                      "_tests": [],
                                      "_refs": [],
                                      "_flags": {},
                                      "_description": null,
                                      "_unit": null,
                                      "_notes": [],
                                      "_tags": [],
                                      "_examples": [],
                                      "_meta": [],
                                      "_inner": {},
                                      "_currentJoi": "[Circular ~.base._currentJoi]"
                                    }
                                  },
                                  {
                                    "schema": {
                                      "isJoi": true,
                                      "_currentJoi": "[Circular ~.base._currentJoi]",
                                      "_type": "object",
                                      "_settings": null,
                                      "_valids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_invalids": {
                                        "_set": {},
                                        "_hasRef": false
                                      },
                                      "_tests": [
                                        {
                                          "func": function (value, state, options) {\n\n            if (value.length === n) {\n                return value;\n            }\n\n            return this.createError('function.arity', { n }, state, options);\n        },
                                          "name": "arity",
                                          "arg": 1
                                        }
                                      ],
                                      "_refs": [],
                                      "_flags": {
                                        "func": true
                                      },
                                      "_description": null,
                                      "_unit": null,
                                      "_notes": [],
                                      "_tags": [],
                                      "_examples": [],
                                      "_meta": [],
                                      "_inner": {
                                        "children": null,
                                        "renames": [],
                                        "dependencies": [],
                                        "patterns": []
                                      }
                                    }
                                  }
                                ]
                              }
                            }
                          }
                        ],
                        "renames": [],
                        "dependencies": [
                          {
                            "type": "or",
                            "key": null,
                            "peers": [
                              "setup",
                              "validate"
                            ]
                          }
                        ],
                        "patterns": []
                      }
                    }
                  ],
                  "exclusions": [],
                  "requireds": []
                }
              }
            }
          ],
          "renames": [],
          "dependencies": [],
          "patterns": []
        }
      },
      "extensionsSchema": {
        "isJoi": true,
        "_currentJoi": "[Circular ~.base._currentJoi]",
        "_type": "array",
        "_settings": {
          "convert": false
        },
        "_valids": {
          "_set": {},
          "_hasRef": false
        },
        "_invalids": {
          "_set": {},
          "_hasRef": false
        },
        "_tests": [],
        "_refs": [],
        "_flags": {
          "sparse": false
        },
        "_description": null,
        "_unit": null,
        "_notes": [],
        "_tags": [],
        "_examples": [],
        "_meta": [],
        "_inner": {
          "items": [
            "[Circular ~.base]",
            {
              "isJoi": true,
              "_currentJoi": "[Circular ~.base._currentJoi]",
              "_type": "object",
              "_settings": null,
              "_valids": {
                "_set": {},
                "_hasRef": false
              },
              "_invalids": {
                "_set": {},
                "_hasRef": false
              },
              "_tests": [
                {
                  "func": function (value, state, options) {\n\n            if (value.length === n) {\n                return value;\n            }\n\n            return this.createError('function.arity', { n }, state, options);\n        },
                  "name": "arity",
                  "arg": 1
                }
              ],
              "_refs": [],
              "_flags": {
                "func": true
              },
              "_description": null,
              "_unit": null,
              "_notes": [],
              "_tags": [],
              "_examples": [],
              "_meta": [],
              "_inner": {
                "children": null,
                "renames": [],
                "dependencies": [],
                "patterns": []
              }
            }
          ],
          "ordereds": [],
          "inclusions": [
            "[Circular ~.base]",
            {
              "isJoi": true,
              "_currentJoi": "[Circular ~.base._currentJoi]",
              "_type": "object",
              "_settings": null,
              "_valids": {
                "_set": {},
                "_hasRef": false
              },
              "_invalids": {
                "_set": {},
                "_hasRef": false
              },
              "_tests": [
                {
                  "func": function (value, state, options) {\n\n            if (value.length === n) {\n                return value;\n            }\n\n            return this.createError('function.arity', { n }, state, options);\n        },
                  "name": "arity",
                  "arg": 1
                }
              ],
              "_refs": [],
              "_flags": {
                "func": true
              },
              "_description": null,
              "_unit": null,
              "_notes": [],
              "_tags": [],
              "_examples": [],
              "_meta": [],
              "_inner": {
                "children": null,
                "renames": [],
                "dependencies": [],
                "patterns": []
              }
            }
          ],
          "exclusions": [],
          "requireds": []
        }
      },
      "version": "15.1.1"
    }
  },
  "coerce": {
    "from": "string",
    "method": "[method(value) {\n                        if (typeof value !== 'string' || (value[0] !== '{' && !/^\\s*\\{/.test(value))) {\n                            return;\n                        }\n\n                        try {\n                            return { value: Bourne.parse(value) };\n                        } catch (ignoreErr) { }\n                    }]"
  },
  �[41m"name"�[0m�[31m [1]: -- missing --�[0m
}
�[31m
[1] "name" is required�[0m
    at Object.exports.process (/tmp/node_modules/@hapi/joi/lib/errors.js:202:19)
    at internals.Object._validateWithOptions (/tmp/node_modules/@hapi/joi/lib/types/any/index.js:763:31)
    at module.exports.internals.Any.root.validate (/tmp/node_modules/@hapi/joi/lib/index.js:145:23)
    at module.exports.internals.Any.root.attempt (/tmp/node_modules/@hapi/joi/lib/index.js:175:29)
    at module.exports.internals.Any.root.assert (/tmp/node_modules/@hapi/joi/lib/index.js:170:14)
    at module.exports.internals.Any.root.extend (/tmp/node_modules/@hapi/joi/lib/index.js:292:18)
    at new SchemaResolver (/tmp/node_modules/enjoi/lib/resolver.js:13:24)
    at Object.exports.schema (/tmp/node_modules/enjoi/index.js:47:12)
    at Object.<anonymous> (/tmp/main.js:3:20)
    at Module._compile (internal/modules/cjs/loader.js:1123:30) {
  isJoi: true,
  details: [
    {
      message: '"name" is required',
      path: [Array],
      type: 'any.required',
      context: [Object]
    }
  ],
  _object: {
    type: 'object',
    base: {
      isJoi: true,
      _type: 'object',
      _settings: null,
      _valids: [InternalSet],
      _invalids: [InternalSet],
      _tests: [],
      _refs: [],
      _flags: {},
      _description: null,
      _unit: null,
      _notes: [],
      _tags: [],
      _examples: [],
      _meta: [],
      _inner: [Object],
      _currentJoi: [Object]
    },
    coerce: { from: 'string', method: [Function: method] }
  },
  annotate: [Function (anonymous)]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant