class-o-mat
Version:
ALPHA VERSION ONLY: class-o-mats will help to create getter-setter functionality with validations that can be attached to a container class for easier coding. Some basic validations are included. class-o-mats also has the ability to store params as bloc
242 lines (182 loc) • 6.79 kB
JavaScript
import Bunyan from 'bunyan';
const log = Bunyan.createLogger({name: "buildField"});
import mixin from 'mixin-decorator';
import merger from 'lodash.merge';
import { NONE } from '../constants/types';
import Stack from '../prototype/stack';
import Queue from '../prototype/queue';
const _buildAsAbstract =(key)=>{
return function() {
throw new Error(`${this.___minionKey} Error: Illegal Abstract Key ${key}`)
}
}
const _buildWithGetAction =(onGetAction, method)=>{
if (onGetAction === NONE) return method;
return function(ts, params, key, value=NONE) {
if (value === NONE) {
const result = method(ts, params, key, value);
onGetAction(ts, result);
return result;
}
return method(ts, params, key, value);
}
}
const _buildWithGetReducer =(onGetReducer, method)=>{
if (onGetReducer === NONE) return method;
return function(ts, params, key, value=NONE) {
if (value === NONE) return onGetReducer(method(ts, params, key, value));
return method(ts, params, key, value);
}
}
const _buildWithValidator =(validator, method)=>{
if ( validator === NONE || validator.meta === true) return method;
return function(ts, params, key, value=NONE, ...p) {
if (value === NONE) return method(ts, params, key, value, ...p);
const isValid = validator(value, ts);
return (isValid === true)
? method(ts, params, key, value, ...p)
: method(ts, params, key, NONE, ...p);
}
}
const _buildWithSetAction =(onSetAction, method)=>{
if (onSetAction === NONE) return method;
return function(ts, params, key, value=NONE) {
if (value === NONE ) return method(ts, params, key, value);
const result = method(ts, params, key, value);
onSetAction(ts, value);
return result;
}
}
const _buildWithSetReducer =(onSetReducer, method)=>{
if (onSetReducer === NONE) return method;
return function(ts, params, key, value=NONE) {
if (value === NONE) return method(ts, params, key, value);
return method(ts, params, key, onSetReducer(value, ts));
}
}
const _buildWithFallback =(fallback, method)=>{
if (fallback === NONE) return method;
return function(ts, params, key, value=NONE) {
if (value === NONE) {
return method(ts, params, key, value) || ts[fallback]();
return method(ts, params, key, value);
}
}
}
const _buildWithNoParamsObject =(paramObjectKey, internalKey, method)=>{
const ___internalKey = '___'+ internalKey;
return function(...p) {
return method(this, this, ___internalKey, ...p);
}
}
const _buildWithParamsObject = (paramObjectKey, internalKey, method)=>{
return function(...p) {
return method(this, this[paramObjectKey], internalKey, ...p);
}
}
const _buildToParamsObject =(paramObjectKey, internalKey, method)=>{
return (paramObjectKey === false)
? _buildWithNoParamsObject(paramObjectKey, internalKey, method)
: _buildWithParamsObject(paramObjectKey, internalKey, method);
}
const _buildWithSetEvent =(onSet, method)=>{
if (onSet === NONE) return method;
return function(ts, params, key, value=NONE) {
if (value === NONE) return method(ts, params, key, value);
const result = method(ts, params, key, value);
onSet(ts, key, value);
return result;
}
}
const _buildWithGetEvent =(onGet, method)=>{
if (onGet === NONE) return method;
return function(ts, params, key, value=NONE) {
if (value === NONE) {
const result = method(ts, params);
onGet(ts, key, result);
return result;
}
return method(ts, params, key, value);
}
}
const _buildMethodOMats =(methodOMats)=>{
if (methodOMats === NONE || methodOMats.length === 0) return [NONE, NONE];
const curryReducer =(reducer, additionToMethod)=>{
return (v)=>additionToMethod(reducer(v));
}
const curryMethodSet =(method, _methodOMats)=>{
const _l = _methodOMats.length;
if (_l === 0) return method;
method = _methodOMats[0]._params.method;
if (_l !== 1) return method;
let i = 1;
for ( ; i !== _l; i++) {
method = curryReducer(method, _methodOMats[i]._params.method)
}
return method;
}
let onGetMethod = NONE;
let onSetMethod = NONE;
const getMethodOMats
= methodOMats.filter((methodOMat)=>methodOMat._params.onGet);
const setMethodOMats
= methodOMats.filter((methodOMat)=>methodOMat._params.onSet);
onGetMethod = curryMethodSet(onGetMethod, getMethodOMats);
onSetMethod = curryMethodSet(onSetMethod, setMethodOMats);
return [onGetMethod, onSetMethod];
}
const _buildAsCollection =(params, method)=>{
const { key, isQueue, isStack } = params;
if (isQueue === false && isStack === false) return [method, NONE];
const ___key = '___' + key;
const CollectionClass = (isStack === true)
? Stack
: Queue;
method = function(value=NONE) {
return new CollectionClass(this, key, ___key, value);
}
params.key = params.internalKey =___key;
params.isQueue = params.isStack = false;
const ___method = build(params);
return [method, ___method];
}
//place holder... for future idea.
// const _buildDataObjects =(dataObjectBuilder, params, method)=>{
// const result = dataObjectBuilder(params, method);
// if (result === false) return method;
// if (dataObjectBuilder(params, method) === false) return method;
// }
const build =(params)=>{
const { key } = params;
if (params.abstract === true) {
return _buildMethods.buildAsAbstract(key);
}
let ___method;
let method = params.accessorGetter(params);
[method, ___method] = _buildAsCollection(params, method);
if (___method !== NONE) return [method, ___method];
const [onGetAction, onSetAction] = _buildMethodOMats(params.actionOMats||NONE);
const [onGetReducer, onSetReducer] = _buildMethodOMats(params.reducerOMats||NONE);
method = _buildWithGetReducer(onGetReducer, method);
method = _buildWithGetAction(onGetAction, method);
method = _buildWithValidator(params.validator, method);
method = _buildWithSetAction(onSetAction, method);
method = _buildWithSetReducer(onSetReducer, method);
method = _buildWithFallback(params.fallback, method);
method = _buildWithSetEvent(params.ON_SET, method);
method = _buildWithGetEvent(params.ON_GET, method);
method = _buildToParamsObject(params.paramObjectKey, params.internalKey, method);
return method;
}
const adjustDefault =(params)=>{
const {_default} = params;
if (params.isQueue === false && params.isStack === false) {
return _default;
}
return (_default === NONE || _default === null)
? []
: Array.isArray(_default) === true
? _default
: [_default];
}
export { build, adjustDefault }