action-creators
Version:
Redux action creators with logging and validation
109 lines (98 loc) • 2.84 kB
JavaScript
;
var createDebug = require('debug');
var Joi = require('joi');
var usedNamespaces = {};
var usedTypes = {};
/**
* Check if object
* @param {*} a
* @returns {boolean}
* @private
*/
function _isObject(a) {
return !!a && a.constructor === Object;
}
/**
* Create a new namespace
* @param {String} namespace
* @returns {{createAction: Function}}
*/
function createNamespace(namespace) {
if (namespace == null) {
throw new Error('namespace is required');
}
if (typeof namespace !== 'string') {
throw new Error('namespace must be a string');
}
if (usedNamespaces[namespace]) {
throw new Error('namespace "' + namespace + '" is already defined');
}
usedNamespaces[namespace] = true;
var debug = createDebug('ac:' + namespace);
/**
* Create an action
* @param {String} type the action type
* @param {Array} argNames the arguments names
* @param {Object} schema the joi schema
* @param {Function} transform the function to transform the created action
* @returns {Function}
*/
function createAction(type, argNames, schema, transform) {
var fullType = namespace + '/' + type;
if (type == null) {
throw new Error('type is required');
}
if (typeof type !== 'string') {
throw new Error('type must be a string');
}
if (usedTypes[fullType]) {
throw new Error('type "' + type + '" is already defined in namespace "' + namespace + '"');
}
if (argNames == null) {
throw new Error('argNames is required');
}
if (!Array.isArray(argNames)) {
throw new Error('argNames must be an array');
}
if (schema == null) {
throw new Error('schema is required');
}
if (!_isObject(schema)) {
throw new Error('schema must be an object');
}
if (transform != null && typeof transform !== 'function') {
throw new Error('transform must be a function');
}
usedTypes[fullType] = true;
// eslint-disable-next-line require-jsdoc
function actionCreator() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var payload = {};
argNames.forEach(function (argName, i) {
payload[argName] = args[i];
});
debug(type, payload);
Joi.assert(payload, schema, 'Validation failed for: "' + fullType + '"');
var action = {
type: fullType,
payload: payload
};
if (transform) {
var transformed = transform(action);
debug(type, 'transformed', transformed);
return transformed;
}
return action;
}
actionCreator.toString = function () {
return fullType;
};
return actionCreator;
}
return {
createAction: createAction
};
}
module.exports = createNamespace;