UNPKG

ruddy

Version:

Modularized state-management tools for modern front-end applications. Manage dispatched messages in a clean and predictable way for either small or large scale projects

160 lines (144 loc) 6.81 kB
import _default17 from 'ramda/src/prop'; import _default16 from 'ramda/src/equals'; import _default15 from 'ramda/src/all'; import _default14 from 'ramda/src/toPairs'; import _default13 from 'ramda/src/filter'; import _default12 from 'ramda/src/values'; import _default11 from 'ramda/src/compose'; import _default10 from 'ramda/src/keys'; import _default9 from 'ramda/src/pick'; import _default8 from 'ramda/src/curry'; import _default7 from 'ramda/src/identity'; import _default6 from 'ramda/src/is'; import _default5 from 'ramda/src/either'; import _default4 from 'ramda/src/cond'; import _default3 from 'ramda/src/map'; import _default2 from 'ramda/src/match'; import _default from 'ramda/src/zip'; import spected from 'spected'; import { invalidStateMachineInputs } from '../machines'; import { isNotEmpty, isStringieThingie, isPlainObj } from '../util/is'; import { duckMiddlewareRules, duxRules, isDux, noDucks } from './schema'; import { pruneInvalidFields, pruneValidatedFields } from '../validators'; /** * A port of [format-util](https://www.npmjs.com/package/format-util) but with * support for %o in addition to %j, %s and %d. * * @param {String} pattern A string value representing the message with any * placeholders marked by %s, %d, %j or %o * @returns {String} A string formatted with the supplied values inserted * (stringified) into its placeholders */ var utilFormat = function utilFormat(pattern) { for (var _len = arguments.length, params = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { params[_key - 1] = arguments[_key]; } return isStringieThingie(pattern) && params.length ? _default(_default2(/(%?)(%([jods]))/g, pattern), _default3(_default4([[_default5(_default6(Number), _default6(String)), _default7], [_default5(_default6(Array), isPlainObj), JSON.stringify]]))(params)).reduce(function (patt, _ref) { var placeholder = _ref[0], value = _ref[1]; return patt.replace(placeholder, value); }, pattern).replace(/%{2,2}/g, '%') : pattern; }; /** * A curried wrapper around [format-util](https://www.npmjs.com/package/format-util) * that places the second param into the placeholder from the first param. * * @func * @sig String -> String -> String * @param {String} description A description of the error message * (friendly to standard message formatting charaacters: %s %o %f etc) * @param {String} message An value to plug into the description using formatting placeholders * @returns {String} A formatted message */ var format = _default8(function (description, message) { return utilFormat(description, message); }); /** * Validates all the configuration options for a new Duck, returning any * validation errors and a filtered version of the config options (just those * that passed validation). * * @func * @sig {k: v} -> {k: v} * @param {Object} options All the configuration options to be passed into the duck constructor * @returns {Object} An object containing the 'validationsResult' * and 'validatedOptions' (which are just all the validated fields) */ export var createDuckSchemaValidator = function createDuckSchemaValidator() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var optionsToValidate = _default9(_default10(duxRules), options); var validationsResult = spected(duxRules, optionsToValidate); var validatedOptions = pruneInvalidFields(optionsToValidate, validationsResult); return { validationsResult: validationsResult, validatedOptions: validatedOptions }; }; // export const createDuckSchemaValidator = compose( // converge(merge, [ // compose( // objOf('validatedOptions'), // converge(pruneInvalidFields, [identity, spected(duxRules)]) // ), // compose(objOf('validationsResult'), spected(duxRules)) // ]), // pick(keys(duxRules)) // ) /** * For a row of ducks, retrieves any invalid inputs for each duck's state machines. * State machines are objects whose keys are states and whose values are objects * inside of which the input value is the key of each of its key/value pairs. * * @func * @sig {k: v} -> {k: v} * @param {Object} row An object of ducks, each containing one or more state machines and action types * @returns {Object} An object of validation error messages about invalid states inputs for each duck's state machines */ export var getInvalidStateMachineInputs = _default11(_default3(format('These inputs are not valid Action Types: %o')), _default13(isNotEmpty), _default3(invalidStateMachineInputs), _default12, _default13(isDux)); /** * For a row of ducks, checks the schema rules for valiation errors. * * @func * @sig {k: v} -> {k: v} * @param {Object} row An object of ducks * @returns {Object} An object of validation error messages corresponding to one or more ducks in the row */ export var getInvalidDucks = _default11(_default3(format('These violations of the schema rules for the middleware were found: %o')), _default13(isNotEmpty), _default3(_default11(pruneValidatedFields, spected(duckMiddlewareRules))), _default12, _default13(isDux)); /** * For a row of ducks, checks if the name given to the duck inside the row maches that duck's store prop. * * @func * @sig {k: v} -> Boolean * @param {Object} row An object of ducks * @returns {Boolean} whether the name for each duck (in the row) matches each duck's store prop */ export var duckNamesMatchStoreNames = _default11(_default15(function (_ref2) { var key = _ref2[0], val = _ref2[1]; return _default16(key, _default17('store', val)); }), _default14, _default13(isDux)); /** * Checks for any validation errors on a row of ducks. * If there are errors, a string description of the problem(s) is returned. * * @func * @sig {k: v} -> String * @param {Object} row An object containing one or more ducks * @returns {String|null} A validation error message or null (if no validation errors) */ export var getRowValidationErrors = function getRowValidationErrors(row) { if (noDucks(row)) { // eslint-disable-next-line max-len return 'No ducks have been provided! To create the ducks middleware please provide an Object containing one or more ducks'; } if (!duckNamesMatchStoreNames(row)) { // eslint-disable-next-line max-len return 'The name of each duck should match its \'store\' prop, otherwise it will not be possible to find the correct duck for each dispatched action'; } var invalidStateMachines = getInvalidStateMachineInputs(row); if (isNotEmpty(invalidStateMachines)) { return format('Invalid State Machines: %o', invalidStateMachines); } var invalidDucks = getInvalidDucks(row); if (isNotEmpty(invalidDucks)) { return format('Invalid Ducks: %o', invalidDucks); } return null; };