1import { some } from 'lodash';
8 validateMaximumPatpByteLength,
12 validateEthereumAddress,
16 validateNotNullAddress,
19} from 'lib/validators';
20import isPromise from 'lib/isPromise';
22const PRIVATE_KEY_CHAR_LENGTH = 64; // 64 hex characters
23const ADDRESS_CHAR_LENGTH = 40; // 40 hex characters
25// iterate over validators, exiting early if there's an error
26const buildValidator = (validators = [], validate) => value => {
27 for (const validator of validators) {
29 const error = validator(value);
40 // the final validate function can optionally return a promise
41 return validate(value);
45// maps a validator across an array of values
46export const buildArrayValidator = validator => values => {
47 const errorsOrPromises = values.map(validator);
48 if (some(errorsOrPromises, isPromise)) {
49 return Promise.all(errorsOrPromises);
52 return errorsOrPromises;
55// error object has errors if some of its fields are
56// 1) an array with any defined values
57// 2) any defined values
58export const hasErrors = iter =>
59 some(iter, v => (Array.isArray(v) ? hasErrors(v) : v !== undefined));
61export const buildPatqValidator = (validators = []) =>
62 buildValidator([validateNotEmpty, validatePatq, ...validators]);
63export const buildMnemonicValidator = () =>
64 buildValidator([validateNotEmpty, validateMnemonic]);
65export const buildCheckboxValidator = mustBe =>
67 validateOneOf(mustBe !== undefined ? [mustBe] : [true, false]),
69export const buildPassphraseValidator = () => buildValidator([]);
70// TODO: validate hdpath format
71export const buildHdPathValidator = () => buildValidator([validateNotEmpty]);
72export const buildPointValidator = (size = 4, validators = []) =>
75 validateMaximumPatpByteLength(size),
79export const buildSelectValidator = options =>
80 buildValidator([validateOneOf(options.map(option => option.value))]);
81export const buildHexValidator = length =>
86 validateHexLength(length),
88export const buildPrivateKeyValidator = () =>
92 validateLength(PRIVATE_KEY_CHAR_LENGTH),
94export const buildUploadValidator = () => buildValidator([validateNotEmpty]);
95export const buildAddressValidator = () =>
100 validateHexLength(ADDRESS_CHAR_LENGTH),
101 validateNotNullAddress,
102 validateEthereumAddress,
104export const buildNumberValidator = (min = 0, max = NaN) =>
105 buildValidator([validateGreaterThan(min), validateLessThan(max)]);
107export const buildEmailValidator = validate =>
108 buildValidator([validateNotEmpty, validateEmail], validate);
110// the form validator is the composition of all of the field validators
111// plus an additional form validator function
112export const composeValidator = (
113 fieldValidators = {},
114 // the default form validator just returns field-level validations
115 formValidator = (values, errors) => errors
117 const names = Object.keys(fieldValidators);
119 const fieldLevelValidators = names.map(name => value =>
120 fieldValidators[name](value)
123 // async reduce errors per-field into an errors object
124 const fieldLevelValidator = values => {
125 const errorsOrPromises = names.map((name, i) =>
126 fieldLevelValidators[i](values[name])
129 const reduce = errors =>
131 (memo, name, i) => ({
138 if (some(errorsOrPromises, isPromise)) {
139 // if any of these results are a promise, await them all then reduce
140 return Promise.all(errorsOrPromises).then(reduce);
143 // otherwise return immediately
144 return reduce(errorsOrPromises);
147 // the final-form `validate` function
148 // NOTE: if we return a Promise to final-form it will toggle the `validating`
149 // state, which is expected. If our promise resolves immediately, however,
150 // that means our `validating` state flickers the UI and it looks pretty bad.
151 // The solution is to conditionally return a promise only when necessary.
153 // ask for field-level errors
154 const errorsOrPromise = fieldLevelValidator(values);
156 // pass the current values and their validity to the form-level validator
157 // that can implement conditional logic and more complex validations
158 const runFormValidator = errors => formValidator(values, errors);
160 if (isPromise(errorsOrPromise)) {
161 // if promise, promise
162 return errorsOrPromise.then(runFormValidator);
165 // otherwise, it's an errors object
166 return runFormValidator(errorsOrPromise);
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list