import omit from 'lodash/omit'; import normalizeUrl from 'normalize-url'; import { isURL } from 'validator'; const normalizeOptions = { stripWWW: false }; // callIfDefined(fn: (Any) => Any) => (value: Any) => Any export function callIfDefined(fn) { return value => value ? fn(value) : value; } // formatUrl(url: String) => String export function formatUrl(url) { if ( typeof url === 'string' && url.length > 4 && url.indexOf('.') !== -1 ) { // prevent trailing / from being stripped during typing let lastChar = ''; if (url.substring(url.length - 1) === '/') { lastChar = '/'; } // prevent normalize-url from stripping last dot during typing if (url.substring(url.length - 1) === '.') { lastChar = '.'; } return normalizeUrl(url, normalizeOptions) + lastChar; } return url; } export function isValidURL(data) { /* eslint-disable quote-props */ return isURL(data, { 'require_protocol': true }); /* eslint-enable quote-props */ } export function makeOptional(validator) { return val => val ? validator(val) : true; } export function makeRequired(validator) { return (val) => val ? validator(val) : false; } export function createFormValidator(fieldValidators) { const fieldKeys = Object.keys(fieldValidators); return values => fieldKeys .map(field => { if (fieldValidators[field](values[field])) { return null; } return { [field]: !fieldValidators[field](values[field]) }; }) .filter(Boolean) .reduce((errors, error) => ({ ...errors, ...error }), {}); } export function getValidationState(field) { if (field.pristine) { return null; } if ((/https?:\/\/glitch\.com\/edit\/#!\/.*/g).test(field.value)) { return 'glitch-warning'; } return field.error ? 'error' : 'success'; } // this should filter out none-dom props to silence React warnings export function DOMOnlyProps(field) { return omit(field, [ 'initialValue', 'autofill', 'autocompleted', 'onUpdate', 'valid', 'invalid', 'dirty', 'pristine', 'active', 'touched', 'visited', 'autofilled', 'error' ]); }