@conform-to/react
Version:
Conform view adapter for react
230 lines (217 loc) • 6.49 kB
JavaScript
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;
;