'use strict'; const Assert = require('@hapi/hoek/lib/assert'); const Base = require('../base'); const Common = require('../common'); const Messages = require('../messages'); const internals = {}; module.exports = Base.extend({ type: 'any', flags: { only: { default: false } }, terms: { alterations: { init: null }, examples: { init: null }, externals: { init: null }, metas: { init: [] }, notes: { init: [] }, shared: { init: null }, tags: { init: [] }, whens: { init: null } }, rules: { custom: { method(method, description) { Assert(typeof method === 'function', 'Method must be a function'); Assert(description === undefined || description && typeof description === 'string', 'Description must be a non-empty string'); return this.$_addRule({ name: 'custom', args: { method, description } }); }, validate(value, helpers, { method }) { try { return method(value, helpers); } catch (err) { return helpers.error('any.custom', { error: err }); } }, args: ['method', 'description'], multi: true }, messages: { method(messages) { return this.prefs({ messages }); } }, shared: { method(schema) { Assert(Common.isSchema(schema) && schema._flags.id, 'Schema must be a schema with an id'); const obj = this.clone(); obj.$_terms.shared = obj.$_terms.shared || []; obj.$_terms.shared.push(schema); obj.$_mutateRegister(schema); return obj; } }, warning: { method(code, local) { Assert(code && typeof code === 'string', 'Invalid warning code'); return this.$_addRule({ name: 'warning', args: { code, local }, warn: true }); }, validate(value, helpers, { code, local }) { return helpers.error(code, local); }, args: ['code', 'local'], multi: true } }, modifiers: { keep(rule, enabled = true) { rule.keep = enabled; }, message(rule, message) { rule.message = Messages.compile(message); }, warn(rule, enabled = true) { rule.warn = enabled; } }, manifest: { build(obj, desc) { for (const key in desc) { const values = desc[key]; if (['examples', 'externals', 'metas', 'notes', 'tags'].includes(key)) { for (const value of values) { obj = obj[key.slice(0, -1)](value); } continue; } if (key === 'alterations') { const alter = {}; for (const { target, adjuster } of values) { alter[target] = adjuster; } obj = obj.alter(alter); continue; } if (key === 'whens') { for (const value of values) { const { ref, is, not, then, otherwise, concat } = value; if (concat) { obj = obj.concat(concat); } else if (ref) { obj = obj.when(ref, { is, not, then, otherwise, switch: value.switch, break: value.break }); } else { obj = obj.when(is, { then, otherwise, break: value.break }); } } continue; } if (key === 'shared') { for (const value of values) { obj = obj.shared(value); } } } return obj; } }, messages: { 'any.custom': '{{#label}} failed custom validation because {{#error.message}}', 'any.default': '{{#label}} threw an error when running default method', 'any.failover': '{{#label}} threw an error when running failover method', 'any.invalid': '{{#label}} contains an invalid value', 'any.only': '{{#label}} must be {if(#valids.length == 1, "", "one of ")}{{#valids}}', 'any.ref': '{{#label}} {{#arg}} references {{:#ref}} which {{#reason}}', 'any.required': '{{#label}} is required', 'any.unknown': '{{#label}} is not allowed' } });