UNPKG

@conform-to/react

Version:

Conform view adapter for react

230 lines (217 loc) 6.49 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _rollupPluginBabelHelpers = require('../_virtual/_rollupPluginBabelHelpers.js'); var future = require('@conform-to/dom/future'); var _excluded = [""]; function isUndefined(value) { return value === undefined; } function isString(value) { return typeof value === 'string'; } function isNumber(value) { return typeof value === 'number'; } function isOptional(value, typeGuard) { return isUndefined(value) || typeGuard(value); } function getArrayAtPath(formValue, name) { var _getValueAtPath; var value = (_getValueAtPath = future.getValueAtPath(formValue, name)) !== null && _getValueAtPath !== void 0 ? _getValueAtPath : []; if (!Array.isArray(value)) { throw new Error("The value of \"".concat(name, "\" is not an array")); } return value; } /** * Immutably updates a value at the specified path. * Empty path replaces the entire object. */ function updateValueAtPath(data, name, value) { if (name === '') { if (!future.isPlainObject(value)) { throw new Error('The value must be an object'); } return value; } return future.setValueAtPath(data, future.getPathSegments(name), value, { clone: true }); } /** * Creates a function that updates array indices in field paths. * Returns null to remove fields, or updated path with new index. */ function createPathIndexUpdater(listName, update) { var listPaths = future.getPathSegments(listName); return name => { var paths = future.getPathSegments(name); if (paths.length > listPaths.length && listPaths.every((path, index) => paths[index] === path)) { var currentIndex = paths[listPaths.length]; if (typeof currentIndex === 'number') { var newIndex = update(currentIndex); if (newIndex === null) { // To remove the item instead of updating it return null; } if (newIndex !== currentIndex) { // Replace the index paths.splice(listPaths.length, 1, newIndex); return future.formatPathSegments(paths); } } } return name; }; } /** * Returns null if error object has no actual error messages, * otherwise returns the error as-is. */ function normalizeFormError(error) { if (error && error.formErrors.length === 0 && Object.entries(error.fieldErrors).every(_ref => { var [, messages] = _ref; return Array.isArray(messages) ? messages.length === 0 : !messages; })) { return null; } return error; } function normalizeValidateResult(result) { if (result !== null && 'error' in result) { return { error: normalizeFormError(result.error), value: result.value }; } return { error: normalizeFormError(result) }; } /** * Handles different validation result formats: * - Promise: async validation only * - Array: [syncResult, asyncPromise] * - Object: sync validation only */ function resolveValidateResult(result) { var syncResult; var asyncResult; if (result instanceof Promise) { asyncResult = result; } else if (Array.isArray(result)) { syncResult = result[0]; asyncResult = result[1]; } else { syncResult = result; } return { syncResult: syncResult ? normalizeValidateResult(syncResult) : undefined, asyncResult: asyncResult ? asyncResult.then(normalizeValidateResult) : undefined }; } function resolveStandardSchemaPath(issue) { if (!issue.path) { return []; } var segments = issue.path.map(segment => typeof segment === 'object' && 'key' in segment ? segment.key : segment); if (!segments.every(segment => typeof segment !== 'symbol')) { throw new Error('Path segments must not contain symbols. Use strings or numbers instead.'); } return segments; } function resolveStandardSchemaResult(result) { if (!result.issues) { return { error: null, value: result.value }; } var errorByName = {}; for (var issue of result.issues) { var _errorByName$_name; var path = resolveStandardSchemaPath(issue); var _name = future.formatPathSegments(path); (_errorByName$_name = errorByName[_name]) !== null && _errorByName$_name !== void 0 ? _errorByName$_name : errorByName[_name] = []; errorByName[_name].push(issue.message); } var { '': formErrors = [] } = errorByName, fieldErrors = _rollupPluginBabelHelpers.objectWithoutProperties(errorByName, _excluded); return { error: { formErrors, fieldErrors } }; } /** * Create a copy of the object with the updated properties if there is any change */ function merge(obj, update) { if (obj === update || Object.entries(update).every(_ref2 => { var [key, value] = _ref2; return obj[key] === value; })) { return obj; } return Object.assign({}, obj, update); } /** * Transforms object keys using a mapping function. * Keys mapped to null are filtered out. */ function transformKeys(obj, fn) { var result = {}; for (var [_key, _value] of Object.entries(obj)) { var _name2 = fn(_key); if (_name2 !== null) { result[_name2] = _value; } } return result; } /** * Appends item to array only if not already present. * Returns original array if item exists, new array if added. */ function appendUniqueItem(list, item) { if (list.includes(item)) { return list; } return list.concat(item); } /** * Maps over array and filters out null results. */ function compactMap(list, fn) { var result = []; for (var item of list) { var _value2 = fn(item); if (_value2 !== null) { result.push(_value2); } } return result; } function generateUniqueKey() { return Math.trunc(Date.now() * Math.random()).toString(36); } exports.appendUniqueItem = appendUniqueItem; exports.compactMap = compactMap; exports.createPathIndexUpdater = createPathIndexUpdater; exports.generateUniqueKey = generateUniqueKey; exports.getArrayAtPath = getArrayAtPath; exports.isNumber = isNumber; exports.isOptional = isOptional; exports.isString = isString; exports.isUndefined = isUndefined; exports.merge = merge; exports.normalizeFormError = normalizeFormError; exports.normalizeValidateResult = normalizeValidateResult; exports.resolveStandardSchemaPath = resolveStandardSchemaPath; exports.resolveStandardSchemaResult = resolveStandardSchemaResult; exports.resolveValidateResult = resolveValidateResult; exports.transformKeys = transformKeys; exports.updateValueAtPath = updateValueAtPath;