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
JavaScript
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;
};