'use strict'; const Assert = require('@hapi/hoek/lib/assert'); const Any = require('./any'); const Common = require('../common'); const Values = require('../values'); const internals = {}; internals.isBool = function (value) { return typeof value === 'boolean'; }; module.exports = Any.extend({ type: 'boolean', flags: { sensitive: { default: false } }, terms: { falsy: { init: null, manifest: 'values' }, truthy: { init: null, manifest: 'values' } }, coerce(value, { schema }) { if (typeof value === 'boolean') { return; } if (typeof value === 'string') { const normalized = schema._flags.sensitive ? value : value.toLowerCase(); value = normalized === 'true' ? true : (normalized === 'false' ? false : value); } if (typeof value !== 'boolean') { value = schema.$_terms.truthy && schema.$_terms.truthy.has(value, null, null, !schema._flags.sensitive) || (schema.$_terms.falsy && schema.$_terms.falsy.has(value, null, null, !schema._flags.sensitive) ? false : value); } return { value }; }, validate(value, { error }) { if (typeof value !== 'boolean') { return { value, errors: error('boolean.base') }; } }, rules: { truthy: { method(...values) { Common.verifyFlat(values, 'truthy'); const obj = this.clone(); obj.$_terms.truthy = obj.$_terms.truthy || new Values(); for (let i = 0; i < values.length; ++i) { const value = values[i]; Assert(value !== undefined, 'Cannot call truthy with undefined'); obj.$_terms.truthy.add(value); } return obj; } }, falsy: { method(...values) { Common.verifyFlat(values, 'falsy'); const obj = this.clone(); obj.$_terms.falsy = obj.$_terms.falsy || new Values(); for (let i = 0; i < values.length; ++i) { const value = values[i]; Assert(value !== undefined, 'Cannot call falsy with undefined'); obj.$_terms.falsy.add(value); } return obj; } }, sensitive: { method(enabled = true) { return this.$_setFlag('sensitive', enabled); } } }, cast: { number: { from: internals.isBool, to(value, helpers) { return value ? 1 : 0; } }, string: { from: internals.isBool, to(value, helpers) { return value ? 'true' : 'false'; } } }, manifest: { build(obj, desc) { if (desc.truthy) { obj = obj.truthy(...desc.truthy); } if (desc.falsy) { obj = obj.falsy(...desc.falsy); } return obj; } }, messages: { 'boolean.base': '{{#label}} must be a boolean' } });