UNPKG

svelte-forms-lib

Version:

Svelte forms lib - A lightweight library for managing forms in Svelte v3

131 lines (109 loc) 3.08 kB
import {dequal as isEqual} from 'dequal/lite'; function subscribeOnce(observable) { return new Promise((resolve) => { observable.subscribe(resolve)(); // immediately invoke to unsubscribe }); } function update(object, path, value) { object.update((o) => { set(o, path, value); return o; }); } function cloneDeep(object) { return JSON.parse(JSON.stringify(object)); } function isNullish(value) { return value === undefined || value === null; } function isEmpty(object) { return isNullish(object) || Object.keys(object).length <= 0; } function getValues(object) { let results = []; for (const [, value] of Object.entries(object)) { const values = typeof value === 'object' ? getValues(value) : [value]; results = [...results, ...values]; } return results; } // TODO: refactor this so as not to rely directly on yup's API // This should use dependency injection, with a default callback which may assume // yup as the validation schema function getErrorsFromSchema(initialValues, schema, errors = {}) { for (const key in schema) { switch (true) { case schema[key].type === 'object' && !isEmpty(schema[key].fields): { errors[key] = getErrorsFromSchema( initialValues[key], schema[key].fields, {...errors[key]}, ); break; } case schema[key].type === 'array': { const values = initialValues && initialValues[key] ? initialValues[key] : []; errors[key] = values.map((value) => { const innerError = getErrorsFromSchema( value, schema[key].innerType.fields, {...errors[key]}, ); return Object.keys(innerError).length > 0 ? innerError : ''; }); break; } default: { errors[key] = ''; } } } return errors; } const deepEqual = isEqual; function assignDeep(object, value) { if (Array.isArray(object)) { return object.map((o) => assignDeep(o, value)); } const copy = {}; for (const key in object) { copy[key] = typeof object[key] === 'object' && !isNullish(object[key]) ? assignDeep(object[key], value) : value; } return copy; } function set(object, path, value) { if (new Object(object) !== object) return object; if (!Array.isArray(path)) { path = path.toString().match(/[^.[\]]+/g) || []; } const result = path .slice(0, -1) // TODO: replace this reduce with something more readable // eslint-disable-next-line unicorn/no-array-reduce .reduce( (accumulator, key, index) => new Object(accumulator[key]) === accumulator[key] ? accumulator[key] : (accumulator[key] = Math.trunc(Math.abs(path[index + 1])) === +path[index + 1] ? [] : {}), object, ); result[path[path.length - 1]] = value; return object; } export const util = { assignDeep, cloneDeep, deepEqual, getErrorsFromSchema, getValues, isEmpty, isNullish, set, subscribeOnce, update, };