Exemple #1
0
 /**
  * Creates a socket event error.
  * @param {String} message - Error message
  * @param {String} [event] - The socket event name
  * @param {Object} [info] - Extra info object
  * @param {Boolean} [isPublic] - Whether the message should be visible to user or not
  */
 constructor (message, event, info, isPublic = false) {
   /* eslint-disable no-param-reassign */
   if (isBoolean(event)) {
     isPublic = event;
     info = undefined;
     event = undefined;
   }
   if (isBoolean(info)) {
     isPublic = info;
     info = undefined;
   }
   super(message, isPublic);
   this.event = event;
   this.info = info;
 }
Exemple #2
0
  /**
   * @param {*} value
   * @param {Field} field
   *
   * @throws {AssertionFailed}
   */
  guard(value, field) {
    if (isBoolean(value)) {
      return;
    }

    throw new AssertionFailed(`Field [${field.getName()}] :: Value [${JSON.stringify(value)}] is not a boolean.`);
  }
Exemple #3
0
  /**
   * @param {*} value
   * @param {Field} field
   * @param {Codec} [codec]
   *
   * @returns {boolean}
   */
  decode(value, field, codec = null) {
    if (isBoolean(value)) {
      return !!value;
    }

    return ['1', 'true', 'yes', 'on', '+'].indexOf(trim(toLower(value))) !== -1;
  }
Exemple #4
0
/**
 * Parses a boolean display string into a real Boolean.
 *
 * It matches :
 *  - real boolean (true/false)
 *  - int boolean (0/1)
 *  - english for yes/no, true/false
 *  - current locale yes/no, true/false
 *
 * @param {boolean|string} value
 * @param {boolean}        silent - if true, does not throw on parse error.
 *
 * @returns {boolean}
 */
function parseBool(value, silent = false) {
  if (isBoolean(value)) {
    return value
  } else if (typeof value === 'string') {
    switch (value.toLowerCase().trim()) {
      case '1':
      case 'true':
      case t('true').toLowerCase().trim():
      case 'yes':
      case t('yes').toLowerCase().trim():
        return true
      case '0':
      case 'false':
      case t('false').toLowerCase().trim():
      case 'no':
      case t('no').toLowerCase().trim():
        return false
    }
  }

  if (!silent) {
    throw new Error('Invalid boolean value.')
  }

  return false
}
Exemple #5
0
function volumePersister (options = {}) {
  if (isBoolean(options)) options = {}; // eslint-disable-line no-param-reassign
  const _options = {...defaults, ...options};
  const {storeName, volumeKey, mutedKey} = _options;
  const storage = localForage.createInstance({storeName});

  storage.getItem(mutedKey)
         .then((muted) => {
           this.muted(!!muted);
         });

  storage.getItem(volumeKey)
         .then((volume) => {
           if (volume !== null && volume >= 0) {
             this.volume(volume);
           }
         });

  this.on('volumechange', () => {
    const volume = this.volume();
    const muted = this.muted();
    storage.setItem(volumeKey, volume);
    storage.setItem(mutedKey, muted);
  });
}
Exemple #6
0
  isVisibilityControlled(props) {
    const { visible, onVisibleChange } = props || this.props;
    const hasOnChange = isFunction(onVisibleChange);
    const hasVisible = isBoolean(visible);

    if ((hasVisible && !hasOnChange) || (hasOnChange && !hasVisible)) {
      throw new Error('visible and onVisibleChange must be used together');
    }

    return hasVisible && hasOnChange;
  }
Exemple #7
0
}, function (amounts, type) {
  if (isBoolean(amounts)) {
    amounts = { after: amounts, before: amounts };
  }

  each([type].concat(t.FLIPPED_ALIAS_KEYS[type] || []), function (type) {
    exports.nodes[type] = function () {
      return amounts;
    };
  });
});
Exemple #8
0
export function arrayify(val: any, mapFn?: Function): Array<any> {
  if (!val) return [];
  if (isBoolean(val)) return arrayify([val], mapFn);
  if (isString(val)) return arrayify(list(val), mapFn);

  if (Array.isArray(val)) {
    if (mapFn) val = val.map(mapFn);
    return val;
  }

  return [val];
}
Exemple #9
0
        const callback = (event, sequence) => {
          // Check we are actually in focus and that a child hasn't already handled this sequence
          const isFocused = isBool(this.props.focused)
            ? this.props.focused
            : this.__isFocused__;

          if (isFocused && sequence !== this.__lastChildSequence__) {
            if (this.context.hotKeyParent) {
              this.context.hotKeyParent.childHandledSequence(sequence);
            }

            return handler(event, sequence);
          }
        };
function castBoolean(format, value, options={}) {
  if (!isBoolean(value)) {
    if (!isString(value)) {
      return ERROR
    }
    value = value.trim()
    if ((options.trueValues || _TRUE_VALUES).includes(value)) {
      value = true
    } else if ((options.falseValues || _FALSE_VALUES).includes(value)) {
      value = false
    } else {
      return ERROR
    }
  }
  return value
}
Exemple #11
0
 forOwn(mod, (value, key) => {
   if (styleSrc[key]) {
     const modStyleSrc = styleSrc[key];
     if (isBoolean(value)) {
       if (value) {
         let modStyle = this._resolveMod(modStyleSrc, mod);
         assign(styleSrc, modStyle);
       }
     }
     else if (isString(value)) {
       if (modStyleSrc[value]) {
         let modStyle = this._resolveMod(modStyleSrc[value], mod);
         assign(styleSrc, modStyle);
       }
     }
   }
 });
const simpleResult = (result) => {
  if (result && result.type)
    return <div className="result__react">{result}</div>;

  if (isFunction(result) && result.name)
    return <i>Function {result.name}</i>;

  if (result === null)
    return 'Null';

  if (isBoolean(result))
    return result ? 'True' : 'False';

  if (isObject(result) || isArray(result))
    return JSON.stringify(result);

  return result;
}
var createTernFile = function (name, code, options) {
  var wrap = isBoolean(options.wrap) ? options.wrap : false;
  var file = {
    name: name,
    text: code
  };
  var context = new infer.Context(defs);
  infer.withContext(context, function () {
    file.ast = infer.parse(file.text, {
      directSourceFile: file,
      allowReturnOutsideFunction: true,
      allowImportExportEverywhere: true,
      ecmaVersion: 6
    });
    file.scope = context.topScope;
    if (wrap) {
      file.scope = buildWrappingScope(file.scope, file.name, file.ast);
    }
    infer.analyze(file.ast, file.text, file.scope);
  });
  return file;
};
const formatResult = (result) => {

  if (result === undefined)
    return <span className="cm-atom">undefined</span>;

  if (result && result.type)
    return <div className="result__react">{result}</div>;

  if (result === null)
    return <span className="cm-atom">null</span>;

  if (result === null)
    return <span className="cm-atom">null</span>;

  if (isBoolean(result))
    return <span className="cm-atom">{result ? 'true' : 'false'}</span>;

  if (isNumber(result)) {
    return <span className="cm-number">{isNaN(result) ? 'NaN' : result}</span>
  }

  if (isString(result))
    return <span className="cm-string">"{result}"</span>

  if (isFunction(result))
    return <em><span className="cm-keyword">function</span> <span className="cm-def">{result.name || 'anonymous'}</span></em>;

  if (isArray(result))
    return <span>[{result.map((v, i, arr) => <span key={i}>{formatResult(v)}{coma(arr, i)}</span>)}]</span>;

  if (isObject(result))
    return <span>{'{ '}{_.map(result, (v, k) => ({k, v})).map(({k, v}, i, arr) =>(
      <span key={k}><span className="cm-property">{k}</span>: {formatResult(v)}{coma(arr, i)}</span>
    ))} {' }'}</span>;

  return result;
};
const forceUnsecureTracker = ( options ) => isObject( options )
    && has.call( options, 'forceUnsecureTracker' ) && isBoolean( options.forceUnsecureTracker )
const respectDoNotTrack = ( options ) => isObject( options )
    && has.call( options, 'respectDoNotTrack' ) && isBoolean( options.respectDoNotTrack )
const userFingerprint = ( options ) => isObject( options )
    && has.call( options, 'userFingerprint' ) && isBoolean( options.userFingerprint )
 each(properties, function(value, name) {
   if (name === 'id' || name === 'type') return;
   if (isString(value) || isNumber(value) || isBoolean(value)) {
     el.attr(name, value);
   }
 });
const encodeBase64 = ( options ) => isObject( options ) && has.call( options, 'encodeBase64' )
    && isBoolean( options.encodeBase64 )
export function isBoolean(value: any): boolean {
  return _isBoolean(value);
}
Exemple #21
0
  run(context, args) {
    const {ctx} = context;
    const {
      assets = {},
      environment,
      sources,
      view
    } = ctx;
    const {globalBundleName} = sources;
    const {
      integrity: integrityData,
      javascript = {},
      styles = {}
    } = assets;
    const {isDev} = environment;
    const {path: viewPath} = view;
    const {type, version = '1.0.0', integrity, cors = true} = args;
    const pageKey = renameKey(viewPath, 'main');
    const pageBundle = javascript[pageKey];
    let tag;

    if (!isDev && integrity && integrityData) {
      this.integrity = integrityData;

      if (isString(cors)) {
        this.cors = cors;
      } else if (isBoolean(cors) && cors) {
        this.cors = 'anonymous';
      }
    }

    this.type = type; //used in the `addIntegrity` method

    switch (type) {
      case 'pantsuit':
        tag = this.addLink({
          src: `https://a.hrc.onl/pantsuit/v${version}/css/pantsuit.css`
        });
        break;
      case 'css':
        const main = !isDev ? Object.keys(styles).reduce((acc, key) => {
          if (key === 'main' || key === 'vendors' || key === pageKey) {
            acc[key] = styles[key];
          }

          return acc;
        }, {}) : assets.assets;

        tag = this.addLink({
          main,
          global: styles[globalBundleName],
          isDev
        });
        break;
      case 'js':
        tag = this.addScript({
          vendors: javascript.vendors,
          main: javascript.main,
          page: pageBundle
        });
        break;
    }

    if (this.integrity) {
      // HACK: previous runs to the get_asset tag were mutating the `this.integrity` state so if `integrity=true` was taken off
      // of one tag, if a previous tag with "integrity" had run, then the following tag would still persist the integrity state
      this.integrity = null;
    }

    if (this.cors) {
      this.cors = null;
    }

    return new nunjucks.runtime.SafeString(tag || '');
  }
const useCookies = ( options ) => isObject( options ) && has.call( options, 'useCookies' )
    && isBoolean( options.useCookies )
const localStorage = ( options ) => isObject( options ) && has.call( options, 'localStorage' )
    && isBoolean( options.localStorage )
  const formReducer = (state = localInitialFormState, action) => {
    if (!action.model) {
      return state;
    }

    const path = toPath(action.model);

    if (!isEqual(path.slice(0, modelPath.length), modelPath)) {
      return state;
    }

    const localPath = path.slice(modelPath.length);
    let errors;
    let validity;

    switch (action.type) {
      case actionTypes.BATCH:
        return action.actions.reduce(formReducer, state);

      case actionTypes.FOCUS:
        return setField(state, localPath, {
          blur: false, // will be deprecated
          focus: true,
          array: Array.isArray(action.value),
        });

      case actionTypes.CHANGE: {
        if (action.silent) return state;

        let setFieldDirtyState = setField(state, localPath, {
          dirty: true, // will be deprecated
          pristine: false,
          value: action.value,
        });

        if (action.removeKeys) {
          const persistKeys = [];

          const removeKeys = Object.keys(state.fields).filter((fieldKey) => {
            const localStringPath = localPath.join('.');

            for (const removeKey of action.removeKeys) {
              const removeKeyPath = `${localStringPath}.${removeKey}`;
              if (startsWith(fieldKey, removeKeyPath)) return true;
            }

            if (startsWith(fieldKey, `${localStringPath}.`)) {
              persistKeys.push(fieldKey);
            }

            return false;
          });

          removeKeys.forEach((removeKey) => {
            setFieldDirtyState = icepick.updateIn(
              setFieldDirtyState,
              ['fields'],
              (field) => icepick.dissoc(field, removeKey));
          });

          persistKeys.forEach((persistKey, index) => {
            const newPersistKeyPath = toPath(persistKey);
            newPersistKeyPath[localPath.length] = index;

            const persistField = getField(state, persistKey);

            // Remove old key
            setFieldDirtyState = icepick.updateIn(
              setFieldDirtyState,
              ['fields'],
              (field) => icepick.dissoc(field, persistKey));

            // Update field to new key
            setFieldDirtyState = setInField(
              setFieldDirtyState,
              newPersistKeyPath,
              persistField);
          });
        }

        return icepick.merge(setFieldDirtyState, {
          dirty: true, // will be deprecated
          pristine: false,
          valid: formIsValid(setFieldDirtyState),
        });
      }

      case actionTypes.SET_DIRTY: {
        const setDirtyState = icepick.merge(state, {
          dirty: true, // will be deprecated
          pristine: false,
        });

        return setField(setDirtyState, localPath, {
          dirty: true, // will be deprecated
          pristine: false,
        });
      }

      case actionTypes.BLUR:
      case actionTypes.SET_TOUCHED: {
        const fieldState = setField(state, localPath, {
          focus: false,
          touched: true,
          retouched: state.submitted || state.submitFailed,
          blur: true, // will be deprecated
          untouched: false, // will be deprecated
        });

        return icepick.merge(fieldState, {
          touched: true,
          retouched: state.submitted || state.submitFailed,
          untouched: false, // will be deprecated
        });
      }

      case actionTypes.SET_PENDING:
        return setField(state, localPath, {
          pending: action.pending,
          submitted: false,
          submitFailed: false,
          retouched: false,
        });

      case actionTypes.SET_VALIDITY: {
        if (isPlainObject(action.validity)) {
          errors = mapValues(action.validity, valid => !valid);
        } else {
          errors = !action.validity;
        }

        const formIsValidState = setInField(state, localPath, {
          errors,
          validity: action.validity,
          valid: isBoolean(errors) ? !errors : every(errors, error => !error),
        });

        return icepick.merge(formIsValidState, {
          valid: formIsValid(formIsValidState),
        });
      }

      case actionTypes.SET_FIELDS_VALIDITY:
        return map(action.fieldsValidity, (fieldValidity, field) =>
          actions.setValidity(`${model}.${field}`, fieldValidity, action.options)
        ).reduce(formReducer, state);

      case actionTypes.SET_ERRORS: {
        if (isPlainObject(action.errors)) {
          validity = mapValues(action.errors, error => !error);
        } else {
          validity = !action.errors;
        }

        const setErrorsState = setInField(state, localPath, {
          errors: action.errors,
          validity,
          valid: isValid(validity),
        });

        return icepick.merge(setErrorsState, {
          valid: formIsValid(setErrorsState),
        });
      }

      case actionTypes.RESET_VALIDITY: {
        let resetValidityState;
        if (!localPath.length) {
          resetValidityState = icepick.setIn(
            state,
            ['valid'],
            true);

          resetValidityState = icepick.setIn(
            resetValidityState,
            ['validity'],
            initialFieldState.validity);

          resetValidityState = icepick.setIn(
            resetValidityState,
            ['errors'],
            initialFieldState.errors);

          Object.keys(resetValidityState.fields).forEach((field) => {
            resetValidityState = icepick.setIn(
              resetValidityState,
              ['fields', field, 'valid'],
              true);

            resetValidityState = icepick.setIn(
              resetValidityState,
              ['fields', field, 'validity'],
              initialFieldState.validity);

            resetValidityState = icepick.setIn(
              resetValidityState,
              ['fields', field, 'errors'],
              initialFieldState.errors);
          });
        } else {
          resetValidityState = icepick.setIn(
            state,
            ['fields', localPath.join('.'), 'valid'],
            true
          );

          resetValidityState = icepick.setIn(
            resetValidityState,
            ['fields', localPath.join('.'), 'validity'],
            initialFieldState.validity
          );

          resetValidityState = icepick.setIn(
            resetValidityState,
            ['fields', localPath.join('.'), 'errors'],
            initialFieldState.errors
          );
        }

        return icepick.merge(resetValidityState, {
          valid: formIsValid(resetValidityState),
        });
      }

      case actionTypes.SET_PRISTINE: {
        let formIsPristine;
        let setPristineState;

        if (!localPath.length) {
          formIsPristine = true;

          setPristineState = icepick.merge(state, {
            fields: mapValues(state.fields, field => ({
              ...field,
              dirty: false, // will be deprecated
              pristine: true,
            })),
          });
        } else {
          setPristineState = setField(state, localPath, {
            dirty: false, // will be deprecated
            pristine: true,
          });

          formIsPristine = every(mapValues(setPristineState.fields, field => field.pristine));
        }

        return icepick.merge(setPristineState, {
          dirty: !formIsPristine, // will be deprecated
          pristine: formIsPristine,
        });
      }

      case actionTypes.SET_UNTOUCHED:
        return setField(state, localPath, {
          touched: false,
          untouched: true, // will be deprecated
        });

      case actionTypes.SET_SUBMITTED:
        return setField(state, localPath, {
          pending: false,
          submitted: !!action.submitted,
          submitFailed: false,
          touched: true,
          untouched: false, // will be deprecated
        });

      case actionTypes.SET_SUBMIT_FAILED:
        return setField(state, localPath, {
          pending: false,
          submitted: false,
          submitFailed: true,
          touched: true,
          untouched: false, // will be deprecated
        });

      case actionTypes.SET_INITIAL:
      case actionTypes.RESET:
        if (!localPath.length) {
          return localInitialFormState;
        }

        return resetField(state, localPath);

      case actionTypes.SET_VIEW_VALUE:
        return setField(state, localPath, {
          viewValue: action.value,
        });

      default:
        return state;
    }
  };
  model.constructor.relations.forEach(relation => {

    if (relation._isPrepared) return;

    // console.log('setRelationsDefaults', model, relation)   

    // shorthand method to quickly check if relation is of hasMany type
    Object.defineProperty(relation, "isHasMany", {
      get: function() {
        return this.type === 'hasMany'
      }
    });

    // shorthand method to quickly check if relation is of hasOne type
    Object.defineProperty(relation, "isHasOne", {
      get: function() {
        return this.type === 'hasOne'
      }
    });

    // set initialValue for relation property
    if (relation.isHasMany) {
      relation.initialValue = [];
    } else if (relation.isHasOne) {
      relation.initialValue = null;
    }

    if (isString(relation.relatedModel)) {
      relation.relatedModel = model.constructor.getModel(relation.relatedModel);
    }

    // property name on model instance to relation(s)
    if (!relation.propertyName) {
      relation.propertyName = lowercaseFirstLetter(relation.relatedModel.name);

      if (relation.isHasMany) {
        relation.propertyName = pluralize(relation.propertyName)
      }
    }

    // json key for embedded json
    if (!relation.jsonKey) {
      relation.jsonKey = underscore(relation.propertyName);
    }

    // key in top level json
    if (!relation.topLevelJsonKey) {
      relation.topLevelJsonKey = tableize(relation.propertyName);
    }

    // foreign key with ids of relations
    if (!relation.foreignKey) {
      if (relation.isHasMany) {
        relation.foreignKey = foreign_key(singularize(relation.propertyName)) + 's';
      } else if (relation.isHasOne) {
        relation.foreignKey = foreign_key(relation.propertyName);
      }
    }

    let name = upperCaseFirstLetter(relation.propertyName);
    if (relation.isHasMany) name = singularize(name);

    // method name to add single relation, will be used as alias
    if (!relation.setMethodName) {      
      relation.setMethodName = `set${name}`;
    }

    // method name to remove single relation, will be used as alias
    if (!relation.removeMethodName) {
      relation.removeMethodName = `remove${name}`;
    }

    let reverseRelation = relation.reverseRelation;

    if (reverseRelation) {      

      if (isBoolean(reverseRelation)) {
        reverseRelation = relation.reverseRelation = {};
      }

      if (!reverseRelation.onDestroy && reverseRelation.onDestroy !== false) {
        reverseRelation.onDestroy = 'removeSelf'
      }

      if (!reverseRelation.propertyName) {
        reverseRelation.propertyName = lowercaseFirstLetter(model.constructor.name);
      }

      let name = upperCaseFirstLetter(reverseRelation.propertyName);

      if (!reverseRelation.setMethodName) {        
        reverseRelation.setMethodName = `set${name}`;
      }

      if (!reverseRelation.removeMethodName) {        
        reverseRelation.removeMethodName = `remove${name}`;
      }

      //console.log('setRelationsDefaults reverseRelation is true', relation.reverseRelation, relation)

    }

    relation._isPrepared = true;

  });
Exemple #26
0
 typeCheck(value: any): boolean {
   return isBoolean(value);
 }
const post = ( options ) => isObject( options ) && has.call( options, 'post' )
    && isBoolean( options.post )
  return (state = createInitialFormState(model), action) => {
    if (!action.model) return state;

    const path = toPath(action.model);

    if (!isEqual(path.slice(0, modelPath.length), modelPath)) {
      return state;
    }

    const localPath = path.slice(modelPath.length);

    switch (action.type) {
      case actionTypes.FOCUS:
        return setField(state, localPath, {
          focus: true,
          blur: false
        });

      case actionTypes.CHANGE:
      case actionTypes.SET_DIRTY:
        state = icepick.merge(state, {
          dirty: true,
          pristine: false,
        });

        return setField(state, localPath, {
          dirty: true,
          pristine: false
        });

      case actionTypes.BLUR:
      case actionTypes.SET_TOUCHED:
        return setField(state, localPath, {
          touched: true,
          untouched: false,
          focus: false,
          blur: true
        });

      case actionTypes.SET_PENDING:
        return setField(state, localPath, {
          pending: action.pending,
          submitted: false
        });

      case actionTypes.SET_VALIDITY:
        const errors = isPlainObject(action.validity)
          ? {
              ...getField(state, localPath).errors,
              ...mapValues(action.validity, (valid) => !valid)
            }
          : !action.validity;

        state = setField(state, localPath, {
          errors,
          valid: isBoolean(errors)
            ? errors
            : every(errors, (error) => !error)
        });

        return icepick.merge(state, {
          valid: every(mapValues(state.fields, (field) => field.valid))
            && every(state.errors, (error) => !error)
        });

      case actionTypes.SET_PRISTINE:
        state = setField(state, localPath, {
          dirty: false,
          pristine: true
        });

        const formIsPristine = every(mapValues(state.fields, (field) => field.pristine));

        return icepick.merge(state, {
          pristine: formIsPristine,
          dirty: !formIsPristine
        });

      case actionTypes.SET_UNTOUCHED:
        return setField(state, localPath, {
          touched: false,
          untouched: true
        });

      case actionTypes.SET_SUBMITTED:
        return setField(state, localPath, {
          pending: false,
          submitted: !!action.submitted
        });

      case actionTypes.SET_INITIAL:
      case actionTypes.RESET:
        return resetField(state, localPath);

      case actionTypes.SET_VIEW_VALUE:
        return setField(state, localPath, {
          viewValue: action.value
        });

      default:
        return state;
    }
  };
const discoverRootDomain = ( options ) => isObject( options )
    && has.call( options, 'discoverRootDomain' ) && isBoolean( options.discoverRootDomain )
function currentRefinedValues({
    container,
    attributes = [],
    onlyListedAttributes = false,
    clearAll = 'before',
    templates = defaultTemplates,
    collapsible = false,
    transformData,
    autoHideContainer = true,
    cssClasses: userCssClasses = {},
  }) {
  const attributesOK = isArray(attributes) &&
    reduce(
      attributes,
      (res, val) =>
        res &&
          isPlainObject(val) &&
          isString(val.name) &&
          (isUndefined(val.label) || isString(val.label)) &&
          (isUndefined(val.template) || isString(val.template) || isFunction(val.template)) &&
          (isUndefined(val.transformData) || isFunction(val.transformData)),
      true);

  const templatesKeys = ['header', 'item', 'clearAll', 'footer'];
  const templatesOK = isPlainObject(templates) &&
    reduce(
      templates,
      (res, val, key) =>
        res &&
          templatesKeys.indexOf(key) !== -1 &&
          (isString(val) || isFunction(val)),
      true
    );

  const userCssClassesKeys = ['root', 'header', 'body', 'clearAll', 'list', 'item', 'link', 'count', 'footer'];
  const userCssClassesOK = isPlainObject(userCssClasses) &&
    reduce(
      userCssClasses,
      (res, val, key) =>
        res &&
         userCssClassesKeys.indexOf(key) !== -1 &&
         isString(val) || isArray(val),
      true);

  const transformDataOK = isUndefined(transformData) ||
    isFunction(transformData) ||
    isPlainObject(transformData) && isFunction(transformData.item);

  const showUsage = false ||
    !(isString(container) || isDomElement(container)) ||
    !isArray(attributes) ||
    !attributesOK ||
    !isBoolean(onlyListedAttributes) ||
    [false, 'before', 'after'].indexOf(clearAll) === -1 ||
    !isPlainObject(templates) ||
    !templatesOK ||
    !transformDataOK ||
    !isBoolean(autoHideContainer) ||
    !userCssClassesOK;

  if (showUsage) {
    throw new Error(usage);
  }

  const containerNode = getContainerNode(container);
  let CurrentRefinedValues = headerFooterHOC(CurrentRefinedValuesComponent);
  if (autoHideContainer === true) {
    CurrentRefinedValues = autoHideContainerHOC(CurrentRefinedValues);
  }

  const attributeNames = map(attributes, attribute => attribute.name);
  const restrictedTo = onlyListedAttributes ? attributeNames : [];

  const attributesObj = reduce(attributes, (res, attribute) => {
    res[attribute.name] = attribute;
    return res;
  }, {});

  return {
    init({helper}) {
      this._clearRefinementsAndSearch = clearRefinementsAndSearch.bind(null, helper, restrictedTo);
    },

    render({results, helper, state, templatesConfig, createURL}) {
      const cssClasses = {
        root: cx(bem(null), userCssClasses.root),
        header: cx(bem('header'), userCssClasses.header),
        body: cx(bem('body'), userCssClasses.body),
        clearAll: cx(bem('clear-all'), userCssClasses.clearAll),
        list: cx(bem('list'), userCssClasses.list),
        item: cx(bem('item'), userCssClasses.item),
        link: cx(bem('link'), userCssClasses.link),
        count: cx(bem('count'), userCssClasses.count),
        footer: cx(bem('footer'), userCssClasses.footer),
      };

      const templateProps = prepareTemplateProps({
        transformData,
        defaultTemplates,
        templatesConfig,
        templates,
      });

      const clearAllURL = createURL(clearRefinementsFromState(state, restrictedTo));

      const refinements = getFilteredRefinements(results, state, attributeNames, onlyListedAttributes);
      const clearRefinementURLs = refinements.map(refinement => createURL(clearRefinementFromState(state, refinement)));
      const clearRefinementClicks = refinements.map(refinement => clearRefinement.bind(null, helper, refinement));

      const shouldAutoHideContainer = refinements.length === 0;

      ReactDOM.render(
        <CurrentRefinedValues
          attributes={attributesObj}
          clearAllClick={this._clearRefinementsAndSearch}
          clearAllPosition={clearAll}
          clearAllURL={clearAllURL}
          clearRefinementClicks={clearRefinementClicks}
          clearRefinementURLs={clearRefinementURLs}
          collapsible={collapsible}
          cssClasses={cssClasses}
          refinements={refinements}
          shouldAutoHideContainer={shouldAutoHideContainer}
          templateProps={templateProps}
        />,
        containerNode
      );
    },
  };
}