all files / stampit/src/ stampit.js

96.15% Statements 75/78
94.12% Branches 48/51
82.35% Functions 14/17
94% Lines 47/50
1 branch Ignored     
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164   370× 688× 101×   587× 44×   543× 10×   533×   370×     35× 35× 35×           17×     23×                                                                                           293× 293×     293× 293×   293×     293× 293×   293×     293× 293×   293×                                                 19×       355× 419×         280×                                      
import compose from './compose';
import isComposable from '../isComposable';
import isStamp from '../isStamp';
import isFunction from './isFunction';
import isObject from './isObject';
import slice from './slice';
import {merge, assign} from './merge';
import values from './values';
 
function extractFunctions() {
  const functions = slice.call(arguments).reduce((result, arg) => {
    if (isFunction(arg)) {
      return result.concat(arg);
    }
    if (Array.isArray(arg)) {
      return result.concat(extractFunctions.apply(null, arg) || []);
    }
    if (isObject(arg)) {
      return result.concat(extractFunctions.apply(null, values(arg)) || []);
    }
    return result;
  }, []);
  return functions.length === 0 ? undefined : functions;
}
 
function composeArgsCall(self, propName, action, args) {
  const descriptor = {};
  descriptor[propName] = action.apply(null, [{}].concat(slice.call(args)));
  return (self.compose || compose).call(self, descriptor);
}
 
const rawUtilities = {
  methods() {
    return composeArgsCall(this, 'methods', assign, arguments);
  },
  properties() {
    return composeArgsCall(this, 'properties', assign, arguments);
  },
  initializers() {
    return (this.compose || compose).call(this, {
      initializers: extractFunctions.apply(null, slice.call(arguments))
    });
  },
  deepProperties() {
    return composeArgsCall(this, 'deepProperties', merge, arguments);
  },
  staticProperties() {
    return composeArgsCall(this, 'staticProperties', assign, arguments);
  },
  staticDeepProperties() {
    return composeArgsCall(this, 'staticDeepProperties', merge, arguments);
  },
  configuration() {
    return composeArgsCall(this, 'configuration', assign, arguments);
  },
  deepConfiguration() {
    return composeArgsCall(this, 'deepConfiguration', merge, arguments);
  }
};
 
function standardiseDescriptor({
  methods,
 
  properties,
  props,
  refs,
 
  initializers,
  init,
 
  deepProperties,
  deepProps,
 
  propertyDescriptors,
 
  staticProperties,
  statics,
 
  staticDeepProperties,
  deepStatics,
 
  staticPropertyDescriptors,
 
  configuration,
  conf,
 
  deepConfiguration,
  deepConf
} = {}) {
  const p = isObject(props) || isObject(refs) || isObject(properties) ?
    assign({}, props, refs, properties) : undefined;
 
  let dp = isObject(deepProps) ? merge({}, deepProps) : undefined;
  dp = isObject(deepProperties) ? merge(dp, deepProperties) : dp;
 
  const sp = isObject(statics) || isObject(staticProperties) ?
    assign({}, statics, staticProperties) : undefined;
 
  let dsp = isObject(deepStatics) ? merge({}, deepStatics) : undefined;
  dsp = isObject(staticDeepProperties) ? merge(dsp, staticDeepProperties) : dsp;
 
  const c = isObject(conf) || isObject(configuration) ?
    assign({}, conf, configuration) : undefined;
 
  let dc = isObject(deepConf) ? merge({}, deepConf) : undefined;
  dc = isObject(deepConfiguration) ? merge(dc, deepConfiguration) : dc;
 
  return {
    methods,
    properties: p,
    initializers: extractFunctions(init, initializers),
    deepProperties: dp,
    staticProperties: sp,
    staticDeepProperties: dsp,
    propertyDescriptors,
    staticPropertyDescriptors,
    configuration: c,
    deepConfiguration: dc
  };
}
 
const baseStampit = compose({
  staticProperties: assign({
    refs: rawUtilities.properties,
    props: rawUtilities.properties,
    init: rawUtilities.initializers,
    deepProps: rawUtilities.deepProperties,
    statics: rawUtilities.staticProperties,
    deepStatics: rawUtilities.staticDeepProperties,
    conf: rawUtilities.configuration,
    deepConf: rawUtilities.deepConfiguration,
 
    create() {
      return this.apply(undefined, arguments);
    },
 
    compose() {
      return compose.apply(this, slice.call(arguments).filter(isComposable)
        .map(arg => isStamp(arg) ? arg : standardiseDescriptor(arg)));
    }
  }, rawUtilities)
});
 
function stampit() {
  return baseStampit.compose.apply(baseStampit, slice.call(arguments));
}
 
export default assign(stampit,
  {
    isStamp,
    isComposable,
    compose: baseStampit.compose,
    refs: rawUtilities.properties,
    props: rawUtilities.properties,
    init: rawUtilities.initializers,
    deepProps: rawUtilities.deepProperties,
    statics: rawUtilities.staticProperties,
    deepStatics: rawUtilities.staticDeepProperties,
    conf: rawUtilities.configuration,
    deepConf: rawUtilities.deepConfiguration
  },
  rawUtilities
);