<commit_before>'use strict';

import Joi from 'joi-browser';

/**
 * AlmondJoi is a thin wrapper around the Joi Validation utility,
 * providing application-specific value added functionality.
 * 
 * Please note that this class NOT intended to be an overall generic
 * utility, rather one that promotes desired application specific
 * heuristics.
 * 
 * AlmondJoi is used to validate multiple fields ... typically from a
 * form.  
 * 
 * 
 * Validation API:
 * ==============
 * 
 * AlmondJoi holds the Joi schema internally.  As such all validate()
 * requests are processed by AlmondJoi, providing an internal
 * post-processing hook, with some value-added methods:
 * 
 *   validate(fields): validationState <hash>
 *   isValid(): boolean
 *   firstFieldInError(): String
 *   allProminentMsgs(): String[]
 * 
 * The validationState is a hash containing an aggregation of all our
 * validation results, which is suitable to determine if React needs to
 * re-generate.
 * 
 * The isValid() is a convenience method to determine if any validation
 * errors exist.
 * 
 * The firstFieldInError() is a convenience method that returns the first
 * field name <String> in error (null for valid).
 * 
 * The allProminentMsgs() is a convenience method that returns all
 * prominent msgs spanning all fields [one per field] (empty array for
 * valid).
 * 
 * 
 * Deterministic Validation
 * ========================
 * 
 * One of the key features of AlmondJoi is that field validation can be
 * promoted early, not just when a Process button is activated.  I
 * understand that an initial form display should not be filled with
 * errors, however, once the user adds data, and leaves the field, in
 * most cases can be validated at that time.  This way the user doesn't
 * have to wait until a Process button is clicked to determine that an
 * invalid field has been entered.
 * 
 * The client of AlmondJoi accomplishes this by keeping track of whether a
 * field has changed (onChange events) and has been visited (onBlur
 * events).
 * 
 * - Initially only selected fields are validated, based on whether the
 *   field has been visited and modified by the user (see:
 *   fieldHasChanged() [activated via onChange event] and
 *   fieldHasBeenVisited() [activated via onBlur event]).
 * 
 * - Ultimately, all fields are validated ... typically when a process
 *   form request is issued (see: activateAllValidation()).
 * 
 * As an example, once an email address has been entered, and the user
 * tabs off of that field, we can validate it:
 * 
 *   xx pic
 * 
 * After a correction:
 * 
 *   xx pic
 * 
 * Of course course, when you click the Pay button, all remaining
 * validation occurs (as always):
 * 
 *   xx pic
 * 
 * 
 * Consolidated Messages
 * =====================
 * 
 * AlmondJoi promotes it's own value-added schema, providing additional per
 * field features (such as a consolidatedMsg and beingValidated).  Here
 * is a sample schema (NOTE: only the joi attribute is REQUIRED, ALL
 * others are OPTIONAL):
 * 
 *  const mySchema = new AlmondJoi({
 *    addr1:      { joi: Joi.string().required(),
 *                  consolidatedMsg: "address line 1 is required",
 *                  beingValidated: true},
 *    zip:        { joi: Joi.string().required().regex(/^\d{5}(-\d{4})?$/, 'ddddd[-dddd]'), 
 *                  consolidatedMsg: "zip is required: format: ddddd[-dddd]" },
 *    email:      { joi: Joi.string().email().required(),
 *                  consolidatedMsg: "Email is required and must be a valid email address" },
 *  });
 * <commit_msg>Refine AlmondJoi JavaDoc<commit_after>'use strict';

import Joi from 'joi-browser';

/**
 * AlmondJoi is a thin wrapper around the Joi Validation utility,
 * providing application-specific value added functionality.
 * 
 * Please note that this class NOT intended to be an overall generic
 * utility, rather one that promotes desired application specific
 * heuristics.
 * 
 * AlmondJoi is used to validate multiple fields ... typically from a
 * form.  
 * 
 * 
 * Validation API:
 * ==============
 * 
 * AlmondJoi holds the Joi schema internally.  As such all validate()
 * requests are processed by AlmondJoi, providing an internal
 * post-processing hook, with some value-added methods:
 * 
 *   validate(fields): validationState <hash>
 *   isValid(): boolean
 *   firstFieldInError(): String
 *   allProminentMsgs(): String[]
 * 
 * The validationState is a hash containing an aggregation of all our
 * validation results, which is suitable to determine if React needs to
 * re-generate.
 * 
 * The isValid() is a convenience method to determine if any validation
 * errors exist.
 * 
 * The firstFieldInError() is a convenience method that returns the first
 * field name <String> in error (null for valid).
 * 
 * The allProminentMsgs() is a convenience method that returns all
 * prominent msgs spanning all fields [one per field] (empty array for
 * valid).
 * 
 * 
 * Deterministic Validation
 * ========================
 * 
 * One of the key features of AlmondJoi is that field validation can be
 * promoted early, not just when a Process button is activated.  I
 * understand that an initial form display should not be filled with
 * errors, however, once the user adds data, and leaves the field, in
 * most cases can be validated at that time.  This way the user doesn't
 * have to wait until a Process button is clicked to determine that an
 * invalid field has been entered.
 * 
 * The client of AlmondJoi accomplishes this by keeping track of whether a
 * field has changed (onChange events) and has been visited (onBlur
 * events).
 * 
 * - Initially only selected fields are validated, based on whether the
 *   field has been visited and modified by the user (see:
 *   fieldHasChanged() [activated via onChange event] and
 *   fieldHasBeenVisited() [activated via onBlur event]).
 * 
 * - Ultimately, all fields are validated ... typically when a process
 *   form request is issued (see: activateAllValidation()).
 * 
 * As an example, once an email address has been entered, and the user
 * tabs off of that field, we can validate it.  Of course course, when
 * you click the Pay button, all remaining validation occurs (as
 * always):
 * 
 * 
 * Consolidated Messages
 * =====================
 * 
 * AlmondJoi promotes it's own value-added schema, providing additional per
 * field features (such as a consolidatedMsg and beingValidated).  Here
 * is a sample schema (NOTE: only the joi attribute is REQUIRED, ALL
 * others are OPTIONAL):
 * 
 *  const mySchema = new AlmondJoi({
 *    addr1:      { joi: Joi.string().required(),
 *                  consolidatedMsg: "address line 1 is required",
 *                  beingValidated: true},
 *    zip:        { joi: Joi.string().required().regex(/^\d{5}(-\d{4})?$/, 'ddddd[-dddd]'), 
 *                  consolidatedMsg: "zip is required: format: ddddd[-dddd]" },
 *    email:      { joi: Joi.string().email().required(),
 *                  consolidatedMsg: "Email is required and must be a valid email address" },
 *  });
 * 
{'fraction_non_alphanumeric': 0.10154150756611512, 'fraction_numerical': 0.001131381699901004, 'mean_word_length': 3.3306797305572564, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7345727', 'n_tokens_mistral': 1949, 'n_tokens_neox': 1832, 'n_words': 857}