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
222 lines (166 loc) • 8.49 kB
JavaScript
'use strict';
exports.__esModule = true;
exports.getRowValidationErrors = exports.duckNamesMatchStoreNames = exports.getInvalidDucks = exports.getInvalidStateMachineInputs = exports.createDuckSchemaValidator = undefined;
var _prop = require('ramda/src/prop');
var _prop2 = _interopRequireDefault(_prop);
var _equals = require('ramda/src/equals');
var _equals2 = _interopRequireDefault(_equals);
var _all = require('ramda/src/all');
var _all2 = _interopRequireDefault(_all);
var _toPairs = require('ramda/src/toPairs');
var _toPairs2 = _interopRequireDefault(_toPairs);
var _filter = require('ramda/src/filter');
var _filter2 = _interopRequireDefault(_filter);
var _values = require('ramda/src/values');
var _values2 = _interopRequireDefault(_values);
var _compose = require('ramda/src/compose');
var _compose2 = _interopRequireDefault(_compose);
var _keys = require('ramda/src/keys');
var _keys2 = _interopRequireDefault(_keys);
var _pick = require('ramda/src/pick');
var _pick2 = _interopRequireDefault(_pick);
var _curry = require('ramda/src/curry');
var _curry2 = _interopRequireDefault(_curry);
var _identity = require('ramda/src/identity');
var _identity2 = _interopRequireDefault(_identity);
var _is = require('ramda/src/is');
var _is2 = _interopRequireDefault(_is);
var _either = require('ramda/src/either');
var _either2 = _interopRequireDefault(_either);
var _cond = require('ramda/src/cond');
var _cond2 = _interopRequireDefault(_cond);
var _map = require('ramda/src/map');
var _map2 = _interopRequireDefault(_map);
var _match = require('ramda/src/match');
var _match2 = _interopRequireDefault(_match);
var _zip = require('ramda/src/zip');
var _zip2 = _interopRequireDefault(_zip);
var _spected = require('spected');
var _spected2 = _interopRequireDefault(_spected);
var _machines = require('../machines');
var _is3 = require('../util/is');
var _schema = require('./schema');
var _validators = require('../validators');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* 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 (0, _is3.isStringieThingie)(pattern) && params.length ? (0, _zip2.default)((0, _match2.default)(/(%?)(%([jods]))/g, pattern), (0, _map2.default)((0, _cond2.default)([[(0, _either2.default)((0, _is2.default)(Number), (0, _is2.default)(String)), _identity2.default], [(0, _either2.default)((0, _is2.default)(Array), _is3.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 = (0, _curry2.default)(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)
*/
var createDuckSchemaValidator = exports.createDuckSchemaValidator = function createDuckSchemaValidator() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var optionsToValidate = (0, _pick2.default)((0, _keys2.default)(_schema.duxRules), options);
var validationsResult = (0, _spected2.default)(_schema.duxRules, optionsToValidate);
var validatedOptions = (0, _validators.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
*/
var getInvalidStateMachineInputs = exports.getInvalidStateMachineInputs = (0, _compose2.default)((0, _map2.default)(format('These inputs are not valid Action Types: %o')), (0, _filter2.default)(_is3.isNotEmpty), (0, _map2.default)(_machines.invalidStateMachineInputs), _values2.default, (0, _filter2.default)(_schema.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
*/
var getInvalidDucks = exports.getInvalidDucks = (0, _compose2.default)((0, _map2.default)(format('These violations of the schema rules for the middleware were found: %o')), (0, _filter2.default)(_is3.isNotEmpty), (0, _map2.default)((0, _compose2.default)(_validators.pruneValidatedFields, (0, _spected2.default)(_schema.duckMiddlewareRules))), _values2.default, (0, _filter2.default)(_schema.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
*/
var duckNamesMatchStoreNames = exports.duckNamesMatchStoreNames = (0, _compose2.default)((0, _all2.default)(function (_ref2) {
var key = _ref2[0],
val = _ref2[1];
return (0, _equals2.default)(key, (0, _prop2.default)('store', val));
}), _toPairs2.default, (0, _filter2.default)(_schema.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)
*/
var getRowValidationErrors = exports.getRowValidationErrors = function getRowValidationErrors(row) {
if ((0, _schema.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 ((0, _is3.isNotEmpty)(invalidStateMachines)) {
return format('Invalid State Machines: %o', invalidStateMachines);
}
var invalidDucks = getInvalidDucks(row);
if ((0, _is3.isNotEmpty)(invalidDucks)) {
return format('Invalid Ducks: %o', invalidDucks);
}
return null;
};