reducer-class
Version:
Boilerplate free class-based reducer creator. Built with TypeScript. Works with Redux and NGRX. Has integration with immer.
72 lines (71 loc) • 2.63 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const constants_1 = require("./constants");
const errors_1 = require("./errors");
const isArrowFunction = (action) => !action.prototype;
const typeGuardActionHasOwnType = (action) => typeof action.type === 'string';
const typeGuardActionIsString = (action) => typeof action === 'string';
const getActionType = (action) => {
if (typeGuardActionIsString(action)) {
return action;
}
if (typeGuardActionHasOwnType(action)) {
return action.type;
}
try {
if (isArrowFunction(action)) {
const actionCreatorArrowFnRes = action();
return actionCreatorArrowFnRes.type;
}
const classInstance = new action();
return classInstance.type;
}
catch (_a) {
return action.toString();
}
};
const checkParamTypeIsAction = (paramType) => {
try {
return typeof paramType.type === 'string' || typeof new paramType().type === 'string';
}
catch (_a) {
return false;
}
};
const ActionReflect = (target, propertyKey) => {
const methodParamTypes = Reflect.getMetadata(constants_1.METADATA_KEY_METHOD_PARAMS, target, propertyKey);
if (!methodParamTypes ||
!Array.isArray(methodParamTypes) ||
(methodParamTypes.length !== 2 && methodParamTypes.length !== 3)) {
throw new errors_1.ActionTypeUnclearError(propertyKey);
}
let actionCandidate = methodParamTypes[1];
if (methodParamTypes.length === 3) {
actionCandidate = methodParamTypes[2];
}
if (!checkParamTypeIsAction(actionCandidate)) {
throw new errors_1.ActionTypeUnclearError(propertyKey);
}
const action = actionCandidate;
const actionType = getActionType(action);
Reflect.defineMetadata(constants_1.METADATA_KEY_ACTION, [actionType], target, propertyKey);
};
const typeGuardActionArgsAreDecoratorProps = (args) => args.length === 3 &&
typeof args[1] === 'string' &&
typeof args[2] === 'object' &&
args[2].configurable !== undefined &&
args[2].enumerable !== undefined;
function Action(...args) {
if (typeGuardActionArgsAreDecoratorProps(args)) {
return ActionReflect(...args);
}
const decorator = (target, propertyKey, descriptor) => {
if (!args.length) {
throw new errors_1.MetadataActionPropsMissingError(propertyKey);
}
const actionTypes = args.map(getActionType);
Reflect.defineMetadata(constants_1.METADATA_KEY_ACTION, actionTypes, target, propertyKey);
};
return decorator;
}
exports.Action = Action;